wineandroid: Check that Android supports the format in IsFormatSupported.
Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
de9d224996
commit
d2f904e07f
|
@ -683,17 +683,112 @@ static HRESULT waveformat_to_pcm(ACImpl *This, const WAVEFORMATEX *fmt, SLAndroi
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT try_open_render_device(SLAndroidDataFormat_PCM_EX *pcm, unsigned int num_buffers, SLObjectItf *out)
|
||||||
|
{
|
||||||
|
SLresult sr;
|
||||||
|
SLDataSource source;
|
||||||
|
SLDataSink sink;
|
||||||
|
SLDataLocator_OutputMix loc_outmix;
|
||||||
|
SLboolean required[2];
|
||||||
|
SLInterfaceID iids[2];
|
||||||
|
SLDataLocator_AndroidSimpleBufferQueue loc_bq;
|
||||||
|
SLObjectItf player;
|
||||||
|
|
||||||
|
loc_bq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
||||||
|
loc_bq.numBuffers = num_buffers;
|
||||||
|
source.pLocator = &loc_bq;
|
||||||
|
source.pFormat = pcm;
|
||||||
|
|
||||||
|
loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
|
||||||
|
loc_outmix.outputMix = outputmix;
|
||||||
|
sink.pLocator = &loc_outmix;
|
||||||
|
sink.pFormat = NULL;
|
||||||
|
|
||||||
|
required[0] = SL_BOOLEAN_TRUE;
|
||||||
|
iids[0] = *pSL_IID_ANDROIDSIMPLEBUFFERQUEUE;
|
||||||
|
required[1] = SL_BOOLEAN_TRUE;
|
||||||
|
iids[1] = *pSL_IID_PLAYBACKRATE;
|
||||||
|
|
||||||
|
sr = SLCALL(engine, CreateAudioPlayer, &player, &source, &sink,
|
||||||
|
2, iids, required);
|
||||||
|
if(sr != SL_RESULT_SUCCESS){
|
||||||
|
WARN("CreateAudioPlayer failed: 0x%x\n", sr);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sr = SLCALL(player, Realize, SL_BOOLEAN_FALSE);
|
||||||
|
if(sr != SL_RESULT_SUCCESS){
|
||||||
|
SLCALL_N(player, Destroy);
|
||||||
|
WARN("Player Realize failed: 0x%x\n", sr);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(out)
|
||||||
|
*out = player;
|
||||||
|
else
|
||||||
|
SLCALL_N(player, Destroy);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT try_open_capture_device(SLAndroidDataFormat_PCM_EX *pcm, unsigned int num_buffers, SLObjectItf *out)
|
||||||
|
{
|
||||||
|
SLresult sr;
|
||||||
|
SLDataSource source;
|
||||||
|
SLDataSink sink;
|
||||||
|
SLDataLocator_IODevice loc_mic;
|
||||||
|
SLboolean required[1];
|
||||||
|
SLInterfaceID iids[1];
|
||||||
|
SLDataLocator_AndroidSimpleBufferQueue loc_bq;
|
||||||
|
SLObjectItf recorder;
|
||||||
|
|
||||||
|
loc_mic.locatorType = SL_DATALOCATOR_IODEVICE;
|
||||||
|
loc_mic.deviceType = SL_IODEVICE_AUDIOINPUT;
|
||||||
|
loc_mic.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
|
||||||
|
loc_mic.device = NULL;
|
||||||
|
source.pLocator = &loc_mic;
|
||||||
|
source.pFormat = NULL;
|
||||||
|
|
||||||
|
loc_bq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
||||||
|
loc_bq.numBuffers = num_buffers;
|
||||||
|
sink.pLocator = &loc_bq;
|
||||||
|
sink.pFormat = pcm;
|
||||||
|
|
||||||
|
required[0] = SL_BOOLEAN_TRUE;
|
||||||
|
iids[0] = *pSL_IID_ANDROIDSIMPLEBUFFERQUEUE;
|
||||||
|
|
||||||
|
sr = SLCALL(engine, CreateAudioRecorder, &recorder, &source, &sink,
|
||||||
|
1, iids, required);
|
||||||
|
if(sr != SL_RESULT_SUCCESS){
|
||||||
|
WARN("CreateAudioRecorder failed: 0x%x\n", sr);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sr = SLCALL(recorder, Realize, SL_BOOLEAN_FALSE);
|
||||||
|
if(sr != SL_RESULT_SUCCESS){
|
||||||
|
SLCALL_N(recorder, Destroy);
|
||||||
|
WARN("Recorder Realize failed: 0x%x\n", sr);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(out)
|
||||||
|
*out = recorder;
|
||||||
|
else
|
||||||
|
SLCALL_N(recorder, Destroy);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
|
static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
|
||||||
AUDCLNT_SHAREMODE mode, DWORD flags, REFERENCE_TIME duration,
|
AUDCLNT_SHAREMODE mode, DWORD flags, REFERENCE_TIME duration,
|
||||||
REFERENCE_TIME period, const WAVEFORMATEX *fmt,
|
REFERENCE_TIME period, const WAVEFORMATEX *fmt,
|
||||||
const GUID *sessionguid)
|
const GUID *sessionguid)
|
||||||
{
|
{
|
||||||
ACImpl *This = impl_from_IAudioClient(iface);
|
ACImpl *This = impl_from_IAudioClient(iface);
|
||||||
int i;
|
int i, num_buffers;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
SLresult sr;
|
SLresult sr;
|
||||||
SLAndroidDataFormat_PCM_EX pcm;
|
SLAndroidDataFormat_PCM_EX pcm;
|
||||||
SLDataLocator_AndroidSimpleBufferQueue loc_bq;
|
|
||||||
|
|
||||||
TRACE("(%p)->(%x, %x, %s, %s, %p, %s)\n", This, mode, flags,
|
TRACE("(%p)->(%x, %x, %s, %s, %p, %s)\n", This, mode, flags,
|
||||||
wine_dbgstr_longlong(duration), wine_dbgstr_longlong(period), fmt, debugstr_guid(sessionguid));
|
wine_dbgstr_longlong(duration), wine_dbgstr_longlong(period), fmt, debugstr_guid(sessionguid));
|
||||||
|
@ -763,43 +858,13 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
num_buffers = This->bufsize_frames / This->period_frames;
|
||||||
|
|
||||||
if(This->dataflow == eRender){
|
if(This->dataflow == eRender){
|
||||||
SLDataSource source;
|
hr = try_open_render_device(&pcm, num_buffers, &This->player);
|
||||||
SLDataSink sink;
|
if(FAILED(hr)){
|
||||||
SLDataLocator_OutputMix loc_outmix;
|
|
||||||
SLboolean required[2];
|
|
||||||
SLInterfaceID iids[2];
|
|
||||||
|
|
||||||
loc_bq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
|
||||||
loc_bq.numBuffers = This->bufsize_frames / This->period_frames;
|
|
||||||
source.pLocator = &loc_bq;
|
|
||||||
source.pFormat = &pcm;
|
|
||||||
|
|
||||||
loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
|
|
||||||
loc_outmix.outputMix = outputmix;
|
|
||||||
sink.pLocator = &loc_outmix;
|
|
||||||
sink.pFormat = NULL;
|
|
||||||
|
|
||||||
required[0] = SL_BOOLEAN_TRUE;
|
|
||||||
iids[0] = *pSL_IID_ANDROIDSIMPLEBUFFERQUEUE;
|
|
||||||
required[1] = SL_BOOLEAN_TRUE;
|
|
||||||
iids[1] = *pSL_IID_PLAYBACKRATE;
|
|
||||||
|
|
||||||
sr = SLCALL(engine, CreateAudioPlayer, &This->player, &source, &sink,
|
|
||||||
2, iids, required);
|
|
||||||
if(sr != SL_RESULT_SUCCESS){
|
|
||||||
WARN("CreateAudioPlayer failed: 0x%x\n", sr);
|
|
||||||
LeaveCriticalSection(&This->lock);
|
LeaveCriticalSection(&This->lock);
|
||||||
return E_FAIL;
|
return hr;
|
||||||
}
|
|
||||||
|
|
||||||
sr = SLCALL(This->player, Realize, SL_BOOLEAN_FALSE);
|
|
||||||
if(sr != SL_RESULT_SUCCESS){
|
|
||||||
SLCALL_N(This->player, Destroy);
|
|
||||||
This->player = NULL;
|
|
||||||
WARN("Player Realize failed: 0x%x\n", sr);
|
|
||||||
LeaveCriticalSection(&This->lock);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sr = SLCALL(This->player, GetInterface, *pSL_IID_ANDROIDSIMPLEBUFFERQUEUE, &This->bufq);
|
sr = SLCALL(This->player, GetInterface, *pSL_IID_ANDROIDSIMPLEBUFFERQUEUE, &This->bufq);
|
||||||
|
@ -820,42 +885,10 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
SLDataSource source;
|
hr = try_open_capture_device(&pcm, num_buffers, &This->recorder);
|
||||||
SLDataSink sink;
|
if(FAILED(hr)){
|
||||||
SLDataLocator_IODevice loc_mic;
|
|
||||||
SLboolean required[1];
|
|
||||||
SLInterfaceID iids[1];
|
|
||||||
|
|
||||||
loc_mic.locatorType = SL_DATALOCATOR_IODEVICE;
|
|
||||||
loc_mic.deviceType = SL_IODEVICE_AUDIOINPUT;
|
|
||||||
loc_mic.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
|
|
||||||
loc_mic.device = NULL;
|
|
||||||
source.pLocator = &loc_mic;
|
|
||||||
source.pFormat = NULL;
|
|
||||||
|
|
||||||
loc_bq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
|
||||||
loc_bq.numBuffers = This->bufsize_frames / This->period_frames;
|
|
||||||
sink.pLocator = &loc_bq;
|
|
||||||
sink.pFormat = &pcm;
|
|
||||||
|
|
||||||
required[0] = SL_BOOLEAN_TRUE;
|
|
||||||
iids[0] = *pSL_IID_ANDROIDSIMPLEBUFFERQUEUE;
|
|
||||||
|
|
||||||
sr = SLCALL(engine, CreateAudioRecorder, &This->recorder, &source, &sink,
|
|
||||||
1, iids, required);
|
|
||||||
if(sr != SL_RESULT_SUCCESS){
|
|
||||||
WARN("CreateAudioRecorder failed: 0x%x\n", sr);
|
|
||||||
LeaveCriticalSection(&This->lock);
|
LeaveCriticalSection(&This->lock);
|
||||||
return E_FAIL;
|
return hr;
|
||||||
}
|
|
||||||
|
|
||||||
sr = SLCALL(This->recorder, Realize, SL_BOOLEAN_FALSE);
|
|
||||||
if(sr != SL_RESULT_SUCCESS){
|
|
||||||
SLCALL_N(This->recorder, Destroy);
|
|
||||||
This->recorder = NULL;
|
|
||||||
WARN("Recorder Realize failed: 0x%x\n", sr);
|
|
||||||
LeaveCriticalSection(&This->lock);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sr = SLCALL(This->recorder, GetInterface, *pSL_IID_ANDROIDSIMPLEBUFFERQUEUE, &This->bufq);
|
sr = SLCALL(This->recorder, GetInterface, *pSL_IID_ANDROIDSIMPLEBUFFERQUEUE, &This->bufq);
|
||||||
|
@ -971,7 +1004,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
|
||||||
|
|
||||||
This->initted = TRUE;
|
This->initted = TRUE;
|
||||||
|
|
||||||
TRACE("numBuffers: %u, bufsize: %u, period: %u\n", loc_bq.numBuffers,
|
TRACE("numBuffers: %u, bufsize: %u, period: %u\n", num_buffers,
|
||||||
This->bufsize_frames, This->period_frames);
|
This->bufsize_frames, This->period_frames);
|
||||||
|
|
||||||
LeaveCriticalSection(&This->lock);
|
LeaveCriticalSection(&This->lock);
|
||||||
|
@ -1083,7 +1116,27 @@ static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient *iface,
|
||||||
*outpwfx = NULL;
|
*outpwfx = NULL;
|
||||||
|
|
||||||
hr = waveformat_to_pcm(This, pwfx, &pcm);
|
hr = waveformat_to_pcm(This, pwfx, &pcm);
|
||||||
|
if(SUCCEEDED(hr)){
|
||||||
|
if(This->dataflow == eRender){
|
||||||
|
hr = try_open_render_device(&pcm, 10, NULL);
|
||||||
|
}else{
|
||||||
|
hr = try_open_capture_device(&pcm, 10, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(FAILED(hr)){
|
||||||
|
if(outpwfx){
|
||||||
|
hr = IAudioClient_GetMixFormat(iface, outpwfx);
|
||||||
|
if(FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = AUDCLNT_E_UNSUPPORTED_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("returning: %08x\n", hr);
|
TRACE("returning: %08x\n", hr);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue