amstream: Implement AMAudioStream::SetFormat.

Signed-off-by: Anton Baskanov <baskanov@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Anton Baskanov 2020-02-25 23:59:28 -06:00 committed by Alexandre Julliard
parent 1ae8e519f4
commit bbf0a93e4e
2 changed files with 208 additions and 4 deletions

View File

@ -183,6 +183,7 @@ struct audio_stream
IPin *peer;
IMemAllocator *allocator;
AM_MEDIA_TYPE mt;
WAVEFORMATEX format;
};
static inline struct audio_stream *impl_from_IAMMediaStream(IAMMediaStream *iface)
@ -519,13 +520,32 @@ static HRESULT WINAPI audio_IAudioMediaStream_GetFormat(IAudioMediaStream *iface
return S_OK;
}
static HRESULT WINAPI audio_IAudioMediaStream_SetFormat(IAudioMediaStream *iface, const WAVEFORMATEX *wave_format)
static HRESULT WINAPI audio_IAudioMediaStream_SetFormat(IAudioMediaStream *iface, const WAVEFORMATEX *format)
{
struct audio_stream *This = impl_from_IAudioMediaStream(iface);
struct audio_stream *stream = impl_from_IAudioMediaStream(iface);
FIXME("(%p/%p)->(%p) stub!\n", iface, This, wave_format);
TRACE("stream %p, format %p.\n", stream, format);
return E_NOTIMPL;
if (!format)
return E_POINTER;
if (format->wFormatTag != WAVE_FORMAT_PCM)
return E_INVALIDARG;
EnterCriticalSection(&stream->cs);
if ((stream->peer && memcmp(format, stream->mt.pbFormat, sizeof(WAVEFORMATEX)))
|| (stream->format.wFormatTag && memcmp(format, &stream->format, sizeof(WAVEFORMATEX))))
{
LeaveCriticalSection(&stream->cs);
return E_INVALIDARG;
}
stream->format = *format;
LeaveCriticalSection(&stream->cs);
return S_OK;
}
static HRESULT WINAPI audio_IAudioMediaStream_CreateSample(IAudioMediaStream *iface, IAudioData *audio_data,

View File

@ -2434,6 +2434,189 @@ static void test_audiostream_get_format(void)
ok(!ref, "Got outstanding refcount %d.\n", ref);
}
static HRESULT set_audiostream_format(const WAVEFORMATEX *format)
{
IAMMultiMediaStream *mmstream = create_ammultimediastream();
IAudioMediaStream *audio_stream;
IMediaStream *stream;
HRESULT hr;
ULONG ref;
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IAudioMediaStream_SetFormat(audio_stream, format);
ref = IAMMultiMediaStream_Release(mmstream);
ok(!ref, "Got outstanding refcount %d.\n", ref);
IAudioMediaStream_Release(audio_stream);
ref = IMediaStream_Release(stream);
ok(!ref, "Got outstanding refcount %d.\n", ref);
return hr;
}
static void test_audiostream_set_format(void)
{
static const WAVEFORMATEX valid_format =
{
.wFormatTag = WAVE_FORMAT_PCM,
.nChannels = 2,
.nSamplesPerSec = 44100,
.wBitsPerSample = 16,
.nBlockAlign = 4,
.nAvgBytesPerSec = 4 * 44100,
};
const AM_MEDIA_TYPE mt =
{
.majortype = MEDIATYPE_Audio,
.subtype = MEDIASUBTYPE_PCM,
.formattype = FORMAT_WaveFormatEx,
.cbFormat = sizeof(WAVEFORMATEX),
.pbFormat = (BYTE *)&valid_format,
};
WAVEFORMATEXTENSIBLE extensible_format;
IAudioMediaStream *audio_stream;
IAMMultiMediaStream *mmstream;
struct testfilter source;
IGraphBuilder *graph;
IMediaStream *stream;
WAVEFORMATEX format;
HRESULT hr;
ULONG ref;
IPin *pin;
hr = set_audiostream_format(&valid_format);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = set_audiostream_format(NULL);
ok(hr == E_POINTER, "Got hr %#x.\n", hr);
extensible_format.Format = valid_format;
extensible_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
extensible_format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
extensible_format.Samples.wValidBitsPerSample = valid_format.wBitsPerSample;
extensible_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
extensible_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
hr = set_audiostream_format(&extensible_format.Format);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
format = valid_format;
format.nBlockAlign = 1;
hr = set_audiostream_format(&format);
ok(hr == S_OK, "Got hr %#x.\n", hr);
format = valid_format;
format.nAvgBytesPerSec = 1234;
hr = set_audiostream_format(&format);
ok(hr == S_OK, "Got hr %#x.\n", hr);
mmstream = create_ammultimediastream();
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IAudioMediaStream_SetFormat(audio_stream, &valid_format);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IAudioMediaStream_GetFormat(audio_stream, &format);
ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
format = valid_format;
format.nChannels = 1;
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
format = valid_format;
format.nSamplesPerSec = 11025;
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
format = valid_format;
format.nAvgBytesPerSec = 1234;
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
format = valid_format;
format.nBlockAlign = 1;
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
format = valid_format;
format.wBitsPerSample = 8;
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
format = valid_format;
format.cbSize = 1;
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
hr = IAudioMediaStream_SetFormat(audio_stream, &valid_format);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ref = IAMMultiMediaStream_Release(mmstream);
ok(!ref, "Got outstanding refcount %d.\n", ref);
IAudioMediaStream_Release(audio_stream);
ref = IMediaStream_Release(stream);
ok(!ref, "Got outstanding refcount %d.\n", ref);
mmstream = create_ammultimediastream();
hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(!!graph, "Expected non-NULL graph.\n");
testfilter_init(&source);
hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
ok(hr == S_OK, "Got hr %#x.\n", hr);
format = valid_format;
format.nChannels = 1;
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
hr = IGraphBuilder_Disconnect(graph, pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
ok(hr == S_OK, "Got hr %#x.\n", hr);
format = valid_format;
format.nChannels = 1;
hr = IAudioMediaStream_SetFormat(audio_stream, &format);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ref = IAMMultiMediaStream_Release(mmstream);
ok(!ref, "Got outstanding refcount %d.\n", ref);
ref = IGraphBuilder_Release(graph);
ok(!ref, "Got outstanding refcount %d.\n", ref);
IPin_Release(pin);
IAudioMediaStream_Release(audio_stream);
ref = IMediaStream_Release(stream);
ok(!ref, "Got outstanding refcount %d.\n", ref);
ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
ok(!ref, "Got outstanding refcount %d.\n", ref);
}
START_TEST(amstream)
{
HANDLE file;
@ -2468,6 +2651,7 @@ START_TEST(amstream)
test_audiodata_set_format();
test_audiostream_get_format();
test_audiostream_set_format();
CoUninitialize();
}