mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
qcap/audiorecord: Implement IAMBufferNegotiation::SuggestAllocatorProperties().
Needed by the Microsoft Silverlight configuration tool. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=36230
This commit is contained in:
parent
c41ba79df7
commit
38b0a4005a
2 changed files with 76 additions and 6 deletions
|
@ -46,6 +46,7 @@ struct audio_record
|
||||||
CRITICAL_SECTION state_cs;
|
CRITICAL_SECTION state_cs;
|
||||||
|
|
||||||
AM_MEDIA_TYPE format;
|
AM_MEDIA_TYPE format;
|
||||||
|
ALLOCATOR_PROPERTIES props;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct audio_record *impl_from_strmbase_filter(struct strmbase_filter *filter)
|
static struct audio_record *impl_from_strmbase_filter(struct strmbase_filter *filter)
|
||||||
|
@ -158,12 +159,18 @@ static HRESULT WINAPI audio_record_source_DecideBufferSize(struct strmbase_sourc
|
||||||
MMRESULT ret;
|
MMRESULT ret;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
props->cBuffers = 4;
|
props->cBuffers = (filter->props.cBuffers == -1) ? 4 : filter->props.cBuffers;
|
||||||
/* This is the algorithm that native uses. The alignment to an even number
|
/* This is the algorithm that native uses. The alignment to an even number
|
||||||
* doesn't make much sense, and may be a bug. */
|
* doesn't make much sense, and may be a bug. */
|
||||||
props->cbBuffer = (format->nAvgBytesPerSec / 2) & ~1;
|
if (filter->props.cbBuffer == -1)
|
||||||
props->cbAlign = 1;
|
props->cbBuffer = (format->nAvgBytesPerSec / 2) & ~1;
|
||||||
props->cbPrefix = 0;
|
else
|
||||||
|
props->cbBuffer = filter->props.cbBuffer & ~1;
|
||||||
|
if (filter->props.cbAlign == -1 || filter->props.cbAlign == 0)
|
||||||
|
props->cbAlign = 1;
|
||||||
|
else
|
||||||
|
props->cbAlign = filter->props.cbAlign;
|
||||||
|
props->cbPrefix = (filter->props.cbPrefix == -1) ? 0 : filter->props.cbPrefix;
|
||||||
|
|
||||||
if (FAILED(hr = IMemAllocator_SetProperties(allocator, props, &ret_props)))
|
if (FAILED(hr = IMemAllocator_SetProperties(allocator, props, &ret_props)))
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -356,10 +363,17 @@ static ULONG WINAPI buffer_negotiation_Release(IAMBufferNegotiation *iface)
|
||||||
static HRESULT WINAPI buffer_negotiation_SuggestAllocatorProperties(
|
static HRESULT WINAPI buffer_negotiation_SuggestAllocatorProperties(
|
||||||
IAMBufferNegotiation *iface, const ALLOCATOR_PROPERTIES *props)
|
IAMBufferNegotiation *iface, const ALLOCATOR_PROPERTIES *props)
|
||||||
{
|
{
|
||||||
FIXME("iface %p, props %p, stub!\n", iface, props);
|
struct audio_record *filter = impl_from_IAMBufferNegotiation(iface);
|
||||||
|
|
||||||
|
TRACE("filter %p, props %p.\n", filter, props);
|
||||||
TRACE("Requested %ld buffers, size %ld, alignment %ld, prefix %ld.\n",
|
TRACE("Requested %ld buffers, size %ld, alignment %ld, prefix %ld.\n",
|
||||||
props->cBuffers, props->cbBuffer, props->cbAlign, props->cbPrefix);
|
props->cBuffers, props->cbBuffer, props->cbAlign, props->cbPrefix);
|
||||||
return E_NOTIMPL;
|
|
||||||
|
EnterCriticalSection(&filter->state_cs);
|
||||||
|
filter->props = *props;
|
||||||
|
LeaveCriticalSection(&filter->state_cs);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI buffer_negotiation_GetAllocatorProperties(
|
static HRESULT WINAPI buffer_negotiation_GetAllocatorProperties(
|
||||||
|
@ -788,6 +802,11 @@ HRESULT audio_record_create(IUnknown *outer, IUnknown **out)
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object->props.cBuffers = -1;
|
||||||
|
object->props.cbBuffer = -1;
|
||||||
|
object->props.cbAlign = -1;
|
||||||
|
object->props.cbPrefix = -1;
|
||||||
|
|
||||||
object->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
|
object->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
|
||||||
strmbase_filter_init(&object->filter, outer, &CLSID_AudioRecord, &filter_ops);
|
strmbase_filter_init(&object->filter, outer, &CLSID_AudioRecord, &filter_ops);
|
||||||
|
|
||||||
|
|
|
@ -618,6 +618,7 @@ static void test_source_allocator(IFilterGraph2 *graph, IMediaControl *control,
|
||||||
IPin *source, struct testfilter *testsink)
|
IPin *source, struct testfilter *testsink)
|
||||||
{
|
{
|
||||||
ALLOCATOR_PROPERTIES props, req_props = {2, 3200, 32, 0};
|
ALLOCATOR_PROPERTIES props, req_props = {2, 3200, 32, 0};
|
||||||
|
IAMBufferNegotiation *negotiation;
|
||||||
IMemAllocator *allocator;
|
IMemAllocator *allocator;
|
||||||
IMediaSample *sample;
|
IMediaSample *sample;
|
||||||
WAVEFORMATEX format;
|
WAVEFORMATEX format;
|
||||||
|
@ -692,6 +693,56 @@ static void test_source_allocator(IFilterGraph2 *graph, IMediaControl *control,
|
||||||
|
|
||||||
IFilterGraph2_Disconnect(graph, source);
|
IFilterGraph2_Disconnect(graph, source);
|
||||||
IFilterGraph2_Disconnect(graph, &testsink->sink.pin.IPin_iface);
|
IFilterGraph2_Disconnect(graph, &testsink->sink.pin.IPin_iface);
|
||||||
|
|
||||||
|
/* Test IAMBufferNegotiation. *This* is respected. */
|
||||||
|
|
||||||
|
IPin_QueryInterface(source, &IID_IAMBufferNegotiation, (void **)&negotiation);
|
||||||
|
|
||||||
|
hr = IAMBufferNegotiation_SuggestAllocatorProperties(negotiation, &req_props);
|
||||||
|
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
init_pcm_mt(&mt, &format, 1, 32000, 16);
|
||||||
|
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink->sink.pin.IPin_iface, &mt);
|
||||||
|
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
todo_wine ok(testsink->sink.pAllocator && testsink->sink.pAllocator != allocator,
|
||||||
|
"Got unexpected allocator %p.\n", testsink->sink.pAllocator);
|
||||||
|
hr = IMemAllocator_GetProperties(testsink->sink.pAllocator, &props);
|
||||||
|
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||||
|
ok(props.cBuffers == req_props.cBuffers, "Got %ld buffers.\n", props.cBuffers);
|
||||||
|
ok(props.cbBuffer == req_props.cbBuffer, "Got size %ld.\n", props.cbBuffer);
|
||||||
|
ok(props.cbAlign == req_props.cbAlign, "Got alignment %ld.\n", props.cbAlign);
|
||||||
|
ok(props.cbPrefix == req_props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
|
||||||
|
|
||||||
|
IFilterGraph2_Disconnect(graph, source);
|
||||||
|
IFilterGraph2_Disconnect(graph, &testsink->sink.pin.IPin_iface);
|
||||||
|
|
||||||
|
for (req_props.cbBuffer = 32000; req_props.cbBuffer < 32050; ++req_props.cbBuffer)
|
||||||
|
{
|
||||||
|
req_props.cBuffers = -1;
|
||||||
|
req_props.cbAlign = 0;
|
||||||
|
hr = IAMBufferNegotiation_SuggestAllocatorProperties(negotiation, &req_props);
|
||||||
|
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
init_pcm_mt(&mt, &format, 1, 32000, 8);
|
||||||
|
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink->sink.pin.IPin_iface, &mt);
|
||||||
|
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
todo_wine ok(testsink->sink.pAllocator && testsink->sink.pAllocator != allocator,
|
||||||
|
"Got unexpected allocator %p.\n", testsink->sink.pAllocator);
|
||||||
|
hr = IMemAllocator_GetProperties(testsink->sink.pAllocator, &props);
|
||||||
|
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||||
|
ok(props.cBuffers == 4, "Got %ld buffers.\n", props.cBuffers);
|
||||||
|
ok(props.cbBuffer == (req_props.cbBuffer & ~1),
|
||||||
|
"Got size %ld for %ld.\n", props.cbBuffer, req_props.cbBuffer);
|
||||||
|
ok(props.cbAlign == 1, "Got alignment %ld.\n", props.cbAlign);
|
||||||
|
ok(props.cbPrefix == req_props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
|
||||||
|
|
||||||
|
IFilterGraph2_Disconnect(graph, source);
|
||||||
|
IFilterGraph2_Disconnect(graph, &testsink->sink.pin.IPin_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
IAMBufferNegotiation_Release(negotiation);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_filter_state(IFilterGraph2 *graph, IMediaControl *control,
|
static void test_filter_state(IFilterGraph2 *graph, IMediaControl *control,
|
||||||
|
|
Loading…
Reference in a new issue