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>
oldstable
Andrew Eikum 2017-10-06 11:20:35 -05:00 committed by Alexandre Julliard
parent de9d224996
commit d2f904e07f
1 changed files with 126 additions and 73 deletions

View File

@ -683,17 +683,112 @@ static HRESULT waveformat_to_pcm(ACImpl *This, const WAVEFORMATEX *fmt, SLAndroi
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,
AUDCLNT_SHAREMODE mode, DWORD flags, REFERENCE_TIME duration,
REFERENCE_TIME period, const WAVEFORMATEX *fmt,
const GUID *sessionguid)
{
ACImpl *This = impl_from_IAudioClient(iface);
int i;
int i, num_buffers;
HRESULT hr;
SLresult sr;
SLAndroidDataFormat_PCM_EX pcm;
SLDataLocator_AndroidSimpleBufferQueue loc_bq;
TRACE("(%p)->(%x, %x, %s, %s, %p, %s)\n", This, mode, flags,
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;
}
num_buffers = This->bufsize_frames / This->period_frames;
if(This->dataflow == eRender){
SLDataSource source;
SLDataSink sink;
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);
hr = try_open_render_device(&pcm, num_buffers, &This->player);
if(FAILED(hr)){
LeaveCriticalSection(&This->lock);
return E_FAIL;
}
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;
return hr;
}
sr = SLCALL(This->player, GetInterface, *pSL_IID_ANDROIDSIMPLEBUFFERQUEUE, &This->bufq);
@ -820,42 +885,10 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
return E_FAIL;
}
}else{
SLDataSource source;
SLDataSink sink;
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);
hr = try_open_capture_device(&pcm, num_buffers, &This->recorder);
if(FAILED(hr)){
LeaveCriticalSection(&This->lock);
return E_FAIL;
}
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;
return hr;
}
sr = SLCALL(This->recorder, GetInterface, *pSL_IID_ANDROIDSIMPLEBUFFERQUEUE, &This->bufq);
@ -971,7 +1004,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
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);
LeaveCriticalSection(&This->lock);
@ -1083,7 +1116,27 @@ static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient *iface,
*outpwfx = NULL;
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);
return hr;
}