-- v7: qasf: Implement ASF Reader filter pin DecideBufferSize. qasf: Implement ASF Reader filter pin_get_media_type. qasf: Implement ASF Reader filter pin_query_accept. winegstreamer: Implement IWMOutputMediaProps_SetMediaType. wmvcore/tests: Add some IWMOutputMediaProps_SetMediaType tests.
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/wmvcore/tests/wmvcore.c | 217 +++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+)
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index fa58caeae35..ccee17d1f1c 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -48,6 +48,61 @@ static BOOL compare_media_types(const WM_MEDIA_TYPE *a, const WM_MEDIA_TYPE *b) && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat); }
+static void init_audio_type(WM_MEDIA_TYPE *mt, const GUID *subtype, UINT bits, UINT channels, UINT rate) +{ + WAVEFORMATEX *format = (WAVEFORMATEX *)(mt + 1); + + format->wFormatTag = subtype->Data1; + format->nChannels = channels; + format->nSamplesPerSec = rate; + format->wBitsPerSample = bits; + format->nBlockAlign = format->nChannels * format->wBitsPerSample / 8; + format->nAvgBytesPerSec = format->nSamplesPerSec * format->nBlockAlign; + format->cbSize = 0; + + mt->majortype = MEDIATYPE_Audio; + mt->subtype = *subtype; + mt->bFixedSizeSamples = TRUE; + mt->bTemporalCompression = FALSE; + mt->lSampleSize = format->nBlockAlign; + mt->formattype = FORMAT_WaveFormatEx; + mt->pUnk = NULL; + mt->cbFormat = sizeof(*format); + mt->pbFormat = (BYTE *)format; +} + +static void init_video_type(WM_MEDIA_TYPE *mt, const GUID *subtype, UINT depth, DWORD compression, const RECT *rect) +{ + VIDEOINFOHEADER *video_info = (VIDEOINFOHEADER *)(mt + 1); + + video_info->rcSource = *rect; + video_info->rcTarget = *rect; + video_info->dwBitRate = 0; + video_info->dwBitErrorRate = 0; + video_info->AvgTimePerFrame = 0; + video_info->bmiHeader.biSize = sizeof(video_info->bmiHeader); + video_info->bmiHeader.biWidth = rect->right; + video_info->bmiHeader.biHeight = rect->bottom; + video_info->bmiHeader.biPlanes = 1; + video_info->bmiHeader.biBitCount = depth; + video_info->bmiHeader.biCompression = compression; + video_info->bmiHeader.biSizeImage = rect->right * rect->bottom * 4; + video_info->bmiHeader.biXPelsPerMeter = 0; + video_info->bmiHeader.biYPelsPerMeter = 0; + video_info->bmiHeader.biClrUsed = 0; + video_info->bmiHeader.biClrImportant = 0; + + mt->majortype = MEDIATYPE_Video; + mt->subtype = *subtype; + mt->bFixedSizeSamples = TRUE; + mt->bTemporalCompression = FALSE; + mt->lSampleSize = video_info->bmiHeader.biSizeImage; + mt->formattype = FORMAT_VideoInfo; + mt->pUnk = NULL; + mt->cbFormat = sizeof(*video_info); + mt->pbFormat = (BYTE *)video_info; +} + static WCHAR *load_resource(const WCHAR *name) { static WCHAR pathW[MAX_PATH]; @@ -1239,6 +1294,81 @@ static void test_sync_reader_types(void) ok(IsEqualGUID(&majortype2, &majortype), "Expected major type %s, got %s.\n", debugstr_guid(&majortype), debugstr_guid(&majortype2));
+ hr = IWMOutputMediaProps_SetMediaType(output_props, NULL); + todo_wine + ok(hr == E_POINTER, "Got hr %#lx.\n", hr); + + memset(mt2_buffer, 0, sizeof(mt2_buffer)); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == E_FAIL, "Got hr %#lx.\n", hr); + + if (IsEqualGUID(&majortype, &MEDIATYPE_Audio)) + { + WAVEFORMATEX *format = (WAVEFORMATEX *)mt->pbFormat; + + init_audio_type(mt2, &MEDIASUBTYPE_IEEE_FLOAT, 32, format->nChannels * 2, format->nSamplesPerSec); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == NS_E_AUDIO_CODEC_NOT_INSTALLED, "Got hr %#lx.\n", hr); + + init_audio_type(mt2, &MEDIASUBTYPE_PCM, 8, 1, 11025); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + init_audio_type(mt2, &MEDIASUBTYPE_IEEE_FLOAT, 32, format->nChannels, format->nSamplesPerSec / 4); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + else + { + VIDEOINFO *info = (VIDEOINFO *)mt->pbFormat; + RECT rect = info->rcTarget; + + init_video_type(mt2, &MEDIASUBTYPE_RGB32, 32, BI_RGB, &rect); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + init_video_type(mt2, &MEDIASUBTYPE_NV12, 12, MAKEFOURCC('N','V','1','2'), &rect); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == NS_E_INVALID_OUTPUT_FORMAT, "Got hr %#lx.\n", hr); + + InflateRect(&rect, 10, 10); + + init_video_type(mt2, &MEDIASUBTYPE_RGB32, 32, BI_RGB, &rect); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == NS_E_INVALID_OUTPUT_FORMAT, "Got hr %#lx.\n", hr); + } + + hr = IWMOutputMediaProps_SetMediaType(output_props, mt); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ref = IWMOutputMediaProps_Release(output_props); ok(!ref, "Got outstanding refcount %ld.\n", ref);
@@ -1293,9 +1423,15 @@ static void test_sync_reader_types(void) ok(IsEqualGUID(&mt->majortype, &majortype), "Got major type %s.\n", debugstr_guid(&mt->majortype));
if (IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio)) + { + ok(IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_PCM), "Got subtype %s.\n", debugstr_guid(&mt->subtype)); check_audio_type(mt); + } else + { + ok(!IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_AYUV), "Got subtype %s.\n", debugstr_guid(&mt->subtype)); check_video_type(mt); + }
memset(&majortype2, 0xcc, sizeof(majortype2)); hr = IWMOutputMediaProps_GetType(output_props, &majortype2); @@ -2444,6 +2580,81 @@ static void test_async_reader_types(void) ok(IsEqualGUID(&majortype2, &majortype), "Expected major type %s, got %s.\n", debugstr_guid(&majortype), debugstr_guid(&majortype2));
+ hr = IWMOutputMediaProps_SetMediaType(output_props, NULL); + todo_wine + ok(hr == E_POINTER, "Got hr %#lx.\n", hr); + + memset(mt2_buffer, 0, sizeof(mt2_buffer)); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == E_FAIL, "Got hr %#lx.\n", hr); + + if (IsEqualGUID(&majortype, &MEDIATYPE_Audio)) + { + WAVEFORMATEX *format = (WAVEFORMATEX *)mt->pbFormat; + + init_audio_type(mt2, &MEDIASUBTYPE_IEEE_FLOAT, 32, format->nChannels * 2, format->nSamplesPerSec); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == NS_E_AUDIO_CODEC_NOT_INSTALLED, "Got hr %#lx.\n", hr); + + init_audio_type(mt2, &MEDIASUBTYPE_PCM, 8, 1, 11025); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + init_audio_type(mt2, &MEDIASUBTYPE_IEEE_FLOAT, 32, format->nChannels, format->nSamplesPerSec / 4); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + else + { + VIDEOINFO *info = (VIDEOINFO *)mt->pbFormat; + RECT rect = info->rcTarget; + + init_video_type(mt2, &MEDIASUBTYPE_RGB32, 32, BI_RGB, &rect); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + init_video_type(mt2, &MEDIASUBTYPE_NV12, 12, MAKEFOURCC('N','V','1','2'), &rect); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == NS_E_INVALID_OUTPUT_FORMAT, "Got hr %#lx.\n", hr); + + InflateRect(&rect, 10, 10); + + init_video_type(mt2, &MEDIASUBTYPE_RGB32, 32, BI_RGB, &rect); + hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMReader_SetOutputProps(reader, output_number, output_props); + todo_wine + ok(hr == NS_E_INVALID_OUTPUT_FORMAT, "Got hr %#lx.\n", hr); + } + + hr = IWMOutputMediaProps_SetMediaType(output_props, mt); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMReader_SetOutputProps(reader, output_number, output_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ref = IWMOutputMediaProps_Release(output_props); ok(!ref, "Got outstanding refcount %ld.\n", ref);
@@ -2520,9 +2731,15 @@ static void test_async_reader_types(void) ok(IsEqualGUID(&mt->majortype, &majortype), "Got major type %s.\n", debugstr_guid(&mt->majortype));
if (IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio)) + { + ok(IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_PCM), "Got subtype %s.\n", debugstr_guid(&mt->subtype)); check_audio_type(mt); + } else + { + ok(!IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_AYUV), "Got subtype %s.\n", debugstr_guid(&mt->subtype)); check_video_type(mt); + }
memset(&majortype2, 0xcc, sizeof(majortype2)); hr = IWMOutputMediaProps_GetType(output_props, &majortype2);
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/wm_reader.c | 42 ++++++++++++++++++++++++++++++++-- dlls/wmvcore/tests/wmvcore.c | 26 --------------------- 2 files changed, 40 insertions(+), 28 deletions(-)
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 8038b61f7a7..3fc6e73f213 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -116,8 +116,18 @@ static HRESULT WINAPI output_props_GetMediaType(IWMOutputMediaProps *iface, WM_M
static HRESULT WINAPI output_props_SetMediaType(IWMOutputMediaProps *iface, WM_MEDIA_TYPE *mt) { - FIXME("iface %p, mt %p, stub!\n", iface, mt); - return E_NOTIMPL; + const struct output_props *props = impl_from_IWMOutputMediaProps(iface); + + TRACE("iface %p, mt %p.\n", iface, mt); + + if (!mt) + return E_POINTER; + + if (!IsEqualGUID(&props->mt.majortype, &mt->majortype)) + return E_FAIL; + + FreeMediaType((AM_MEDIA_TYPE *)&props->mt); + return CopyMediaType((AM_MEDIA_TYPE *)&props->mt, (AM_MEDIA_TYPE *)mt); }
static HRESULT WINAPI output_props_GetStreamGroupName(IWMOutputMediaProps *iface, WCHAR *name, WORD *len) @@ -1754,6 +1764,7 @@ HRESULT wm_reader_set_output_props(struct wm_reader *reader, DWORD output, struct output_props *props = unsafe_impl_from_IWMOutputMediaProps(props_iface); struct wg_format format, pref_format; struct wm_stream *stream; + int i;
strmbase_dump_media_type(&props->mt);
@@ -1780,6 +1791,33 @@ HRESULT wm_reader_set_output_props(struct wm_reader *reader, DWORD output, return NS_E_INCOMPATIBLE_FORMAT; }
+ switch (pref_format.major_type) + { + case WG_MAJOR_TYPE_AUDIO: + if (format.u.audio.format != WG_AUDIO_FORMAT_S16LE + && format.u.audio.format != WG_AUDIO_FORMAT_F32LE) + return NS_E_AUDIO_CODEC_NOT_INSTALLED; + if (format.u.audio.channels > pref_format.u.audio.channels) + return NS_E_AUDIO_CODEC_NOT_INSTALLED; + break; + + case WG_MAJOR_TYPE_VIDEO: + for (i = 0; i < ARRAY_SIZE(video_formats); ++i) + if (format.u.video.format == video_formats[i]) + break; + if (i == ARRAY_SIZE(video_formats)) + return NS_E_INVALID_OUTPUT_FORMAT; + + if (pref_format.u.video.width != format.u.video.width) + return NS_E_INVALID_OUTPUT_FORMAT; + if (pref_format.u.video.height != format.u.video.height) + return NS_E_INVALID_OUTPUT_FORMAT; + break; + + default: + return NS_E_INCOMPATIBLE_FORMAT; + } + stream->format = format; wg_parser_stream_enable(stream->wg_stream, &format);
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index ccee17d1f1c..dc6dfb8fa30 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -1295,12 +1295,10 @@ static void test_sync_reader_types(void) debugstr_guid(&majortype), debugstr_guid(&majortype2));
hr = IWMOutputMediaProps_SetMediaType(output_props, NULL); - todo_wine ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
memset(mt2_buffer, 0, sizeof(mt2_buffer)); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
if (IsEqualGUID(&majortype, &MEDIATYPE_Audio)) @@ -1309,15 +1307,12 @@ static void test_sync_reader_types(void)
init_audio_type(mt2, &MEDIASUBTYPE_IEEE_FLOAT, 32, format->nChannels * 2, format->nSamplesPerSec); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); - todo_wine ok(hr == NS_E_AUDIO_CODEC_NOT_INSTALLED, "Got hr %#lx.\n", hr);
init_audio_type(mt2, &MEDIASUBTYPE_PCM, 8, 1, 11025); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); todo_wine @@ -1325,10 +1320,8 @@ static void test_sync_reader_types(void)
init_audio_type(mt2, &MEDIASUBTYPE_IEEE_FLOAT, 32, format->nChannels, format->nSamplesPerSec / 4); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); } else @@ -1338,15 +1331,12 @@ static void test_sync_reader_types(void)
init_video_type(mt2, &MEDIASUBTYPE_RGB32, 32, BI_RGB, &rect); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
init_video_type(mt2, &MEDIASUBTYPE_NV12, 12, MAKEFOURCC('N','V','1','2'), &rect); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); todo_wine @@ -1356,15 +1346,12 @@ static void test_sync_reader_types(void)
init_video_type(mt2, &MEDIASUBTYPE_RGB32, 32, BI_RGB, &rect); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); - todo_wine ok(hr == NS_E_INVALID_OUTPUT_FORMAT, "Got hr %#lx.\n", hr); }
hr = IWMOutputMediaProps_SetMediaType(output_props, mt); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); ok(hr == S_OK, "Got hr %#lx.\n", hr); @@ -2581,12 +2568,10 @@ static void test_async_reader_types(void) debugstr_guid(&majortype), debugstr_guid(&majortype2));
hr = IWMOutputMediaProps_SetMediaType(output_props, NULL); - todo_wine ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
memset(mt2_buffer, 0, sizeof(mt2_buffer)); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
if (IsEqualGUID(&majortype, &MEDIATYPE_Audio)) @@ -2595,15 +2580,12 @@ static void test_async_reader_types(void)
init_audio_type(mt2, &MEDIASUBTYPE_IEEE_FLOAT, 32, format->nChannels * 2, format->nSamplesPerSec); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMReader_SetOutputProps(reader, output_number, output_props); - todo_wine ok(hr == NS_E_AUDIO_CODEC_NOT_INSTALLED, "Got hr %#lx.\n", hr);
init_audio_type(mt2, &MEDIASUBTYPE_PCM, 8, 1, 11025); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMReader_SetOutputProps(reader, output_number, output_props); todo_wine @@ -2611,10 +2593,8 @@ static void test_async_reader_types(void)
init_audio_type(mt2, &MEDIASUBTYPE_IEEE_FLOAT, 32, format->nChannels, format->nSamplesPerSec / 4); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMReader_SetOutputProps(reader, output_number, output_props); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); } else @@ -2624,15 +2604,12 @@ static void test_async_reader_types(void)
init_video_type(mt2, &MEDIASUBTYPE_RGB32, 32, BI_RGB, &rect); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMReader_SetOutputProps(reader, output_number, output_props); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
init_video_type(mt2, &MEDIASUBTYPE_NV12, 12, MAKEFOURCC('N','V','1','2'), &rect); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMReader_SetOutputProps(reader, output_number, output_props); todo_wine @@ -2642,15 +2619,12 @@ static void test_async_reader_types(void)
init_video_type(mt2, &MEDIASUBTYPE_RGB32, 32, BI_RGB, &rect); hr = IWMOutputMediaProps_SetMediaType(output_props, mt2); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMReader_SetOutputProps(reader, output_number, output_props); - todo_wine ok(hr == NS_E_INVALID_OUTPUT_FORMAT, "Got hr %#lx.\n", hr); }
hr = IWMOutputMediaProps_SetMediaType(output_props, mt); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMReader_SetOutputProps(reader, output_number, output_props); ok(hr == S_OK, "Got hr %#lx.\n", hr);
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/qasf/asfreader.c | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 13b6e2d7bbe..8f97667752c 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -48,6 +48,57 @@ struct asf_reader struct asf_stream streams[16]; };
+static inline struct asf_stream *impl_from_strmbase_pin(struct strmbase_pin *iface) +{ + return CONTAINING_RECORD(iface, struct asf_stream, source.pin); +} + +static inline struct asf_reader *asf_reader_from_asf_stream(struct asf_stream *stream) +{ + return CONTAINING_RECORD(stream, struct asf_reader, streams[stream->index]); +} + +static HRESULT asf_stream_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *media_type) +{ + struct asf_stream *stream = impl_from_strmbase_pin(iface); + struct asf_reader *filter = asf_reader_from_asf_stream(stream); + IWMOutputMediaProps *props; + WM_MEDIA_TYPE *mt; + DWORD size, i = 0; + HRESULT hr; + + TRACE("iface %p, media_type %p.\n", iface, media_type); + + if (FAILED(hr = IWMReader_GetOutputFormat(filter->reader, stream->index, i, &props))) + return hr; + if (FAILED(hr = IWMOutputMediaProps_GetMediaType(props, NULL, &size))) + { + IWMOutputMediaProps_Release(props); + return hr; + } + if (!(mt = malloc(size))) + { + IWMOutputMediaProps_Release(props); + return E_OUTOFMEMORY; + } + + do + { + if (SUCCEEDED(hr = IWMOutputMediaProps_GetMediaType(props, mt, &size)) + && IsEqualGUID(&mt->majortype, &media_type->majortype) + && IsEqualGUID(&mt->subtype, &media_type->subtype)) + { + IWMOutputMediaProps_Release(props); + break; + } + + IWMOutputMediaProps_Release(props); + } while (SUCCEEDED(hr = IWMReader_GetOutputFormat(filter->reader, stream->index, ++i, &props))); + + free(mt); + return hr; +} + static inline struct asf_reader *impl_from_strmbase_filter(struct strmbase_filter *iface) { return CONTAINING_RECORD(iface, struct asf_reader, filter); @@ -120,6 +171,7 @@ static HRESULT WINAPI asf_reader_DecideBufferSize(struct strmbase_source *iface,
static const struct strmbase_source_ops source_ops = { + .base.pin_query_accept = asf_stream_query_accept, .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator, .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, .pfnDecideBufferSize = asf_reader_DecideBufferSize,
From: R��mi Bernon rbernon@codeweavers.com
And name pins accordingly. --- dlls/qasf/asfreader.c | 45 ++++++++++++++++++++++++++++++++++++- dlls/qasf/tests/asfreader.c | 4 +--- 2 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 8f97667752c..738b6e63548 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -99,6 +99,39 @@ static HRESULT asf_stream_query_accept(struct strmbase_pin *iface, const AM_MEDI return hr; }
+static HRESULT asf_stream_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *media_type) +{ + struct asf_stream *stream = impl_from_strmbase_pin(iface); + struct asf_reader *filter = asf_reader_from_asf_stream(stream); + IWMOutputMediaProps *props; + WM_MEDIA_TYPE *mt; + DWORD size; + HRESULT hr; + + TRACE("iface %p, index %u, media_type %p.\n", iface, index, media_type); + + if (FAILED(IWMReader_GetOutputFormat(filter->reader, stream->index, index, &props))) + return VFW_S_NO_MORE_ITEMS; + if (FAILED(hr = IWMOutputMediaProps_GetMediaType(props, NULL, &size))) + { + IWMOutputMediaProps_Release(props); + return hr; + } + if (!(mt = malloc(size))) + { + IWMOutputMediaProps_Release(props); + return E_OUTOFMEMORY; + } + + hr = IWMOutputMediaProps_GetMediaType(props, mt, &size); + if (SUCCEEDED(hr)) + hr = CopyMediaType(media_type, (AM_MEDIA_TYPE *)mt); + + free(mt); + IWMOutputMediaProps_Release(props); + return hr; +} + static inline struct asf_reader *impl_from_strmbase_filter(struct strmbase_filter *iface) { return CONTAINING_RECORD(iface, struct asf_reader, filter); @@ -172,6 +205,7 @@ static HRESULT WINAPI asf_reader_DecideBufferSize(struct strmbase_source *iface, static const struct strmbase_source_ops source_ops = { .base.pin_query_accept = asf_stream_query_accept, + .base.pin_get_media_type = asf_stream_get_media_type, .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator, .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, .pfnDecideBufferSize = asf_reader_DecideBufferSize, @@ -327,6 +361,7 @@ static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STA WMT_ATTR_DATATYPE type, BYTE *value, void *context) { struct asf_reader *filter = impl_from_IWMReaderCallback(iface)->filter; + AM_MEDIA_TYPE stream_media_type = {0}; DWORD i, stream_count; WCHAR name[MAX_PATH];
@@ -356,7 +391,15 @@ static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STA for (i = 0; i < stream_count; ++i) { struct asf_stream *stream = filter->streams + i; - swprintf(name, ARRAY_SIZE(name), L"Raw Stream %u", stream->index); + + if (FAILED(hr = asf_stream_get_media_type(&stream->source.pin, 0, &stream_media_type))) + WARN("Failed to get stream media type, hr %#lx.\n", hr); + if (IsEqualGUID(&stream_media_type.majortype, &MEDIATYPE_Video)) + swprintf(name, ARRAY_SIZE(name), L"Raw Video %u", stream->index); + else + swprintf(name, ARRAY_SIZE(name), L"Raw Audio %u", stream->index); + FreeMediaType(&stream_media_type); + strmbase_source_init(&stream->source, &filter->filter, name, &source_ops); } filter->stream_count = stream_count; diff --git a/dlls/qasf/tests/asfreader.c b/dlls/qasf/tests/asfreader.c index 494d0384ac8..ed78a856003 100644 --- a/dlls/qasf/tests/asfreader.c +++ b/dlls/qasf/tests/asfreader.c @@ -231,13 +231,11 @@ static void check_pin(IPin *pin, IBaseFilter *expect_filter, PIN_DIRECTION expec ok(hr == S_OK, "Got hr %#lx.\n", hr); ok(info.pFilter == expect_filter, "Got filter %p.\n", info.pFilter); ok(info.dir == expect_dir, "Got dir %#x.\n", info.dir); - todo_wine ok(!wcscmp(info.achName, expect_name), "Got name %s.\n", debugstr_w(info.achName)); IBaseFilter_Release(info.pFilter);
hr = IPin_QueryId(pin, &id); ok(hr == S_OK, "Got hr %#lx.\n", hr); - todo_wine ok(!wcscmp(id, expect_id), "Got id %s.\n", debugstr_w(id)); CoTaskMemFree(id);
@@ -253,7 +251,7 @@ static void check_pin(IPin *pin, IBaseFilter *expect_filter, PIN_DIRECTION expec FreeMediaType(mt); CoTaskMemFree(mt); } - todo_wine + todo_wine_if(IsEqualGUID(&expect_mt[0].majortype, &MEDIATYPE_Video)) ok(i == expect_mt_count, "Got %u types.\n", i); ok(hr == S_FALSE, "Got hr %#lx.\n", hr); IEnumMediaTypes_Release(enum_mt);
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/qasf/asfreader.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 738b6e63548..43a7a3534a8 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -198,8 +198,29 @@ static const struct strmbase_filter_ops filter_ops = static HRESULT WINAPI asf_reader_DecideBufferSize(struct strmbase_source *iface, IMemAllocator *allocator, ALLOCATOR_PROPERTIES *req_props) { - FIXME("iface %p, allocator %p, req_props %p stub!\n", iface, allocator, req_props); - return E_NOTIMPL; + struct asf_stream *stream = impl_from_strmbase_pin(&iface->pin); + unsigned int buffer_size = 16384; + ALLOCATOR_PROPERTIES ret_props; + + TRACE("iface %p, allocator %p, req_props %p.\n", iface, allocator, req_props); + + if (IsEqualGUID(&stream->source.pin.mt.formattype, &FORMAT_VideoInfo)) + { + VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)stream->source.pin.mt.pbFormat; + buffer_size = format->bmiHeader.biSizeImage; + } + else if (IsEqualGUID(&stream->source.pin.mt.formattype, &FORMAT_WaveFormatEx) + && (IsEqualGUID(&stream->source.pin.mt.subtype, &MEDIASUBTYPE_PCM) + || IsEqualGUID(&stream->source.pin.mt.subtype, &MEDIASUBTYPE_IEEE_FLOAT))) + { + WAVEFORMATEX *format = (WAVEFORMATEX *)stream->source.pin.mt.pbFormat; + buffer_size = format->nAvgBytesPerSec; + } + + req_props->cBuffers = max(req_props->cBuffers, 1); + req_props->cbBuffer = max(req_props->cbBuffer, buffer_size); + req_props->cbAlign = max(req_props->cbAlign, 1); + return IMemAllocator_SetProperties(allocator, req_props, &ret_props); }
static const struct strmbase_source_ops source_ops =
v7: Rebase on latest master, only include media type patches for now.
On Fri Aug 5 07:25:14 2022 +0000, **** wrote:
Marvin replied on the mailing list:
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=120582 Your paranoid android. === debian11 (32 bit report) === wmvcore: wmvcore.c:1345: Test succeeded inside todo block: Stream 0: Got hr 0. wmvcore.c:1324: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:1332: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:2631: Test succeeded inside todo block: Output 0: Got hr 0. wmvcore.c:2610: Test succeeded inside todo block: Output 1: Got hr 0. wmvcore.c:2618: Test succeeded inside todo block: Output 1: Got hr 0. === debian11 (32 bit Arabic:Morocco report) === wmvcore: wmvcore.c:1345: Test succeeded inside todo block: Stream 0: Got hr 0. wmvcore.c:1324: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:1332: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:2631: Test succeeded inside todo block: Output 0: Got hr 0. wmvcore.c:2610: Test succeeded inside todo block: Output 1: Got hr 0. wmvcore.c:2618: Test succeeded inside todo block: Output 1: Got hr 0. === debian11 (32 bit German report) === wmvcore: wmvcore.c:1345: Test succeeded inside todo block: Stream 0: Got hr 0. wmvcore.c:1324: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:1332: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:2631: Test succeeded inside todo block: Output 0: Got hr 0. wmvcore.c:2610: Test succeeded inside todo block: Output 1: Got hr 0. wmvcore.c:2618: Test succeeded inside todo block: Output 1: Got hr 0. === debian11 (32 bit French report) === wmvcore: wmvcore.c:1345: Test succeeded inside todo block: Stream 0: Got hr 0. wmvcore.c:1324: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:1332: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:2631: Test succeeded inside todo block: Output 0: Got hr 0. wmvcore.c:2610: Test succeeded inside todo block: Output 1: Got hr 0. wmvcore.c:2618: Test succeeded inside todo block: Output 1: Got hr 0. === debian11 (32 bit Hebrew:Israel report) === wmvcore: wmvcore.c:1345: Test succeeded inside todo block: Stream 0: Got hr 0. wmvcore.c:1324: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:1332: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:2631: Test succeeded inside todo block: Output 0: Got hr 0. wmvcore.c:2610: Test succeeded inside todo block: Output 1: Got hr 0. wmvcore.c:2618: Test succeeded inside todo block: Output 1: Got hr 0. === debian11 (32 bit Hindi:India report) === wmvcore: wmvcore.c:1345: Test succeeded inside todo block: Stream 0: Got hr 0. wmvcore.c:1324: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:1332: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:2631: Test succeeded inside todo block: Output 0: Got hr 0. wmvcore.c:2610: Test succeeded inside todo block: Output 1: Got hr 0. wmvcore.c:2618: Test succeeded inside todo block: Output 1: Got hr 0. === debian11 (32 bit Japanese:Japan report) === wmvcore: wmvcore.c:1345: Test succeeded inside todo block: Stream 0: Got hr 0. wmvcore.c:1324: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:1332: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:2631: Test succeeded inside todo block: Output 0: Got hr 0. wmvcore.c:2610: Test succeeded inside todo block: Output 1: Got hr 0. wmvcore.c:2618: Test succeeded inside todo block: Output 1: Got hr 0. === debian11 (32 bit Chinese:China report) === wmvcore: wmvcore.c:1345: Test succeeded inside todo block: Stream 0: Got hr 0. wmvcore.c:1324: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:1332: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:2631: Test succeeded inside todo block: Output 0: Got hr 0. wmvcore.c:2610: Test succeeded inside todo block: Output 1: Got hr 0. wmvcore.c:2618: Test succeeded inside todo block: Output 1: Got hr 0. === debian11 (32 bit WoW report) === wmvcore: wmvcore.c:1345: Test succeeded inside todo block: Stream 0: Got hr 0. wmvcore.c:1324: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:1332: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:2631: Test succeeded inside todo block: Output 0: Got hr 0. wmvcore.c:2610: Test succeeded inside todo block: Output 1: Got hr 0. wmvcore.c:2618: Test succeeded inside todo block: Output 1: Got hr 0. === debian11 (64 bit WoW report) === wmvcore: wmvcore.c:1345: Test succeeded inside todo block: Stream 0: Got hr 0. wmvcore.c:1324: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:1332: Test succeeded inside todo block: Stream 1: Got hr 0. wmvcore.c:2631: Test succeeded inside todo block: Output 0: Got hr 0. wmvcore.c:2610: Test succeeded inside todo block: Output 1: Got hr 0. wmvcore.c:2618: Test succeeded inside todo block: Output 1: Got hr 0.
These are new. But success seems systematic so it should be an easy fix.