mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-28 16:27:17 +00:00
[client] spice: allow spice startup to happen in parallel
This commit is contained in:
parent
b6fedf1420
commit
4b8255aa28
@ -78,7 +78,6 @@ struct AppParams g_params = { 0 };
|
||||
|
||||
static void lgInit(void)
|
||||
{
|
||||
g_state.state = APP_STATE_RUNNING;
|
||||
g_state.formatValid = false;
|
||||
g_state.resizeDone = true;
|
||||
|
||||
@ -766,8 +765,132 @@ int main_frameThread(void * unused)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void audioStart(int channels, int sampleRate, PSAudioFormat format,
|
||||
uint32_t time)
|
||||
{
|
||||
/*
|
||||
* we probe here so that the audiodev is operating in the context of the SPICE
|
||||
* thread/loop to avoid any audio API threading issues
|
||||
*/
|
||||
static int probed = false;
|
||||
if (!probed)
|
||||
{
|
||||
probed = true;
|
||||
|
||||
// search for the best audiodev to use
|
||||
for(int i = 0; i < LG_AUDIODEV_COUNT; ++i)
|
||||
if (LG_AudioDevs[i]->init())
|
||||
{
|
||||
g_state.audioDev = LG_AudioDevs[i];
|
||||
DEBUG_INFO("Using AudioDev: %s", g_state.audioDev->name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!g_state.audioDev)
|
||||
DEBUG_WARN("Failed to initialize an audio backend");
|
||||
}
|
||||
|
||||
if (g_state.audioDev)
|
||||
{
|
||||
static int lastChannels = 0;
|
||||
static int lastSampleRate = 0;
|
||||
|
||||
if (g_state.audioStarted)
|
||||
{
|
||||
if (channels != lastChannels || sampleRate != lastSampleRate)
|
||||
g_state.audioDev->stop();
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
lastChannels = channels;
|
||||
lastSampleRate = sampleRate;
|
||||
g_state.audioStarted = true;
|
||||
|
||||
DEBUG_INFO("%d channels @ %dHz", channels, sampleRate);
|
||||
g_state.audioDev->start(channels, sampleRate);
|
||||
}
|
||||
}
|
||||
|
||||
static void audioStop(void)
|
||||
{
|
||||
if (g_state.audioDev)
|
||||
g_state.audioDev->stop();
|
||||
g_state.audioStarted = false;
|
||||
}
|
||||
|
||||
static void audioVolume(int channels, const uint16_t volume[])
|
||||
{
|
||||
if (g_state.audioDev && g_state.audioDev->volume)
|
||||
g_state.audioDev->volume(channels, volume);
|
||||
}
|
||||
|
||||
static void audioMute(bool mute)
|
||||
{
|
||||
if (g_state.audioDev && g_state.audioDev->mute)
|
||||
g_state.audioDev->mute(mute);
|
||||
}
|
||||
|
||||
static void audioData(uint8_t * data, size_t size)
|
||||
{
|
||||
if (g_state.audioDev)
|
||||
g_state.audioDev->play(data, size);
|
||||
}
|
||||
|
||||
int spiceThread(void * arg)
|
||||
{
|
||||
const struct PSConfig config =
|
||||
{
|
||||
.host = g_params.spiceHost,
|
||||
.port = g_params.spicePort,
|
||||
.password = "",
|
||||
.log =
|
||||
{
|
||||
.info = debug_info,
|
||||
.warn = debug_warn,
|
||||
.error = debug_error,
|
||||
},
|
||||
.clipboard =
|
||||
{
|
||||
.enable = g_params.useSpiceClipboard,
|
||||
.notice = cb_spiceNotice,
|
||||
.data = cb_spiceData,
|
||||
.release = cb_spiceRelease,
|
||||
.request = cb_spiceRequest
|
||||
},
|
||||
.playback =
|
||||
{
|
||||
.enable = g_params.useSpiceAudio,
|
||||
.start = audioStart,
|
||||
.volume = audioVolume,
|
||||
.mute = audioMute,
|
||||
.stop = audioStop,
|
||||
.data = audioData
|
||||
}
|
||||
};
|
||||
|
||||
if (!purespice_connect(&config))
|
||||
{
|
||||
DEBUG_ERROR("Failed to connect to spice server");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// wait for spice to finish connecting
|
||||
while(g_state.state != APP_STATE_SHUTDOWN && !purespice_ready())
|
||||
{
|
||||
PSStatus status;
|
||||
if ((status = purespice_process(1000)) != PS_STATUS_RUN)
|
||||
{
|
||||
if (status != PS_STATUS_SHUTDOWN)
|
||||
DEBUG_ERROR("Failed to process spice messages");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
// set the intial mouse mode
|
||||
purespice_mouseMode(true);
|
||||
|
||||
// process all spice messages
|
||||
while(g_state.state != APP_STATE_SHUTDOWN)
|
||||
{
|
||||
PSStatus status;
|
||||
@ -775,10 +898,12 @@ int spiceThread(void * arg)
|
||||
{
|
||||
if (status != PS_STATUS_SHUTDOWN)
|
||||
DEBUG_ERROR("failed to process spice messages");
|
||||
break;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
if (g_state.audioDev)
|
||||
{
|
||||
g_state.audioDev->free();
|
||||
@ -853,78 +978,6 @@ static void reportBadVersion()
|
||||
DEBUG_ERROR("Please install the matching host application for this client");
|
||||
}
|
||||
|
||||
void audioStart(int channels, int sampleRate, PSAudioFormat format,
|
||||
uint32_t time)
|
||||
{
|
||||
/*
|
||||
* we probe here so that the audiodev is operating in the context of the SPICE
|
||||
* thread/loop to avoid any audio API threading issues
|
||||
*/
|
||||
static int probed = false;
|
||||
if (!probed)
|
||||
{
|
||||
probed = true;
|
||||
|
||||
// search for the best audiodev to use
|
||||
for(int i = 0; i < LG_AUDIODEV_COUNT; ++i)
|
||||
if (LG_AudioDevs[i]->init())
|
||||
{
|
||||
g_state.audioDev = LG_AudioDevs[i];
|
||||
DEBUG_INFO("Using AudioDev: %s", g_state.audioDev->name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!g_state.audioDev)
|
||||
DEBUG_WARN("Failed to initialize an audio backend");
|
||||
}
|
||||
|
||||
if (g_state.audioDev)
|
||||
{
|
||||
static int lastChannels = 0;
|
||||
static int lastSampleRate = 0;
|
||||
|
||||
if (g_state.audioStarted)
|
||||
{
|
||||
if (channels != lastChannels || sampleRate != lastSampleRate)
|
||||
g_state.audioDev->stop();
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
lastChannels = channels;
|
||||
lastSampleRate = sampleRate;
|
||||
g_state.audioStarted = true;
|
||||
|
||||
DEBUG_INFO("%d channels @ %dHz", channels, sampleRate);
|
||||
g_state.audioDev->start(channels, sampleRate);
|
||||
}
|
||||
}
|
||||
|
||||
static void audioStop(void)
|
||||
{
|
||||
if (g_state.audioDev)
|
||||
g_state.audioDev->stop();
|
||||
g_state.audioStarted = false;
|
||||
}
|
||||
|
||||
static void audioVolume(int channels, const uint16_t volume[])
|
||||
{
|
||||
if (g_state.audioDev && g_state.audioDev->volume)
|
||||
g_state.audioDev->volume(channels, volume);
|
||||
}
|
||||
|
||||
static void audioMute(bool mute)
|
||||
{
|
||||
if (g_state.audioDev && g_state.audioDev->mute)
|
||||
g_state.audioDev->mute(mute);
|
||||
}
|
||||
|
||||
static void audioData(uint8_t * data, size_t size)
|
||||
{
|
||||
if (g_state.audioDev)
|
||||
g_state.audioDev->play(data, size);
|
||||
}
|
||||
|
||||
static int lg_run(void)
|
||||
{
|
||||
g_cursor.sens = g_params.mouseSens;
|
||||
@ -999,60 +1052,10 @@ static int lg_run(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// try to connect to the spice server
|
||||
if (g_params.useSpiceInput ||
|
||||
g_params.useSpiceClipboard ||
|
||||
g_params.useSpiceAudio)
|
||||
{
|
||||
const struct PSConfig config =
|
||||
{
|
||||
.host = g_params.spiceHost,
|
||||
.port = g_params.spicePort,
|
||||
.password = "",
|
||||
.log =
|
||||
{
|
||||
.info = debug_info,
|
||||
.warn = debug_warn,
|
||||
.error = debug_error,
|
||||
},
|
||||
.clipboard =
|
||||
{
|
||||
.enable = g_params.useSpiceClipboard,
|
||||
.notice = cb_spiceNotice,
|
||||
.data = cb_spiceData,
|
||||
.release = cb_spiceRelease,
|
||||
.request = cb_spiceRequest
|
||||
},
|
||||
.playback =
|
||||
{
|
||||
.enable = g_params.useSpiceAudio,
|
||||
.start = audioStart,
|
||||
.volume = audioVolume,
|
||||
.mute = audioMute,
|
||||
.stop = audioStop,
|
||||
.data = audioData
|
||||
}
|
||||
};
|
||||
|
||||
if (!purespice_connect(&config))
|
||||
{
|
||||
DEBUG_ERROR("Failed to connect to spice server");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(g_state.state != APP_STATE_SHUTDOWN && !purespice_ready())
|
||||
{
|
||||
PSStatus status;
|
||||
if ((status = purespice_process(1000)) != PS_STATUS_RUN)
|
||||
{
|
||||
g_state.state = APP_STATE_SHUTDOWN;
|
||||
if (status != PS_STATUS_SHUTDOWN)
|
||||
DEBUG_ERROR("Failed to process spice messages");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
purespice_mouseMode(true);
|
||||
if (!lgCreateThread("spiceThread", spiceThread, NULL, &t_spice))
|
||||
{
|
||||
DEBUG_ERROR("spice create thread failed");
|
||||
@ -1311,6 +1314,8 @@ restart:
|
||||
core_stopFrameThread();
|
||||
core_stopCursorThread();
|
||||
|
||||
|
||||
g_state.state = APP_STATE_RUNNING;
|
||||
lgInit();
|
||||
|
||||
RENDERER(onRestart);
|
||||
|
Loading…
Reference in New Issue
Block a user