output_plugin: add method delay()
This method is used to reduce the delay of commands issued to the shout plugin.
This commit is contained in:
parent
ad430c6617
commit
2dc6ed7b3a
@ -100,6 +100,16 @@ struct audio_output_plugin {
|
|||||||
*/
|
*/
|
||||||
void (*close)(void *data);
|
void (*close)(void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a positive number if the output thread shall delay
|
||||||
|
* the next call to play() or pause(). This should be
|
||||||
|
* implemented instead of doing a sleep inside the plugin,
|
||||||
|
* because this allows MPD to listen to commands meanwhile.
|
||||||
|
*
|
||||||
|
* @return the number of milliseconds to wait
|
||||||
|
*/
|
||||||
|
unsigned (*delay)(void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display metadata for the next chunk. Optional method,
|
* Display metadata for the next chunk. Optional method,
|
||||||
* because not all devices can display metadata.
|
* because not all devices can display metadata.
|
||||||
@ -202,6 +212,14 @@ ao_plugin_close(const struct audio_output_plugin *plugin, void *data)
|
|||||||
plugin->close(data);
|
plugin->close(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
ao_plugin_delay(const struct audio_output_plugin *plugin, void *data)
|
||||||
|
{
|
||||||
|
return plugin->delay != NULL
|
||||||
|
? plugin->delay(data)
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
ao_plugin_send_tag(const struct audio_output_plugin *plugin,
|
ao_plugin_send_tag(const struct audio_output_plugin *plugin,
|
||||||
void *data, const struct tag *tag)
|
void *data, const struct tag *tag)
|
||||||
|
@ -278,6 +278,30 @@ ao_reopen(struct audio_output *ao)
|
|||||||
ao_open(ao);
|
ao_open(ao);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait until the output's delay reaches zero.
|
||||||
|
*
|
||||||
|
* @return true if playback should be continued, false if a command
|
||||||
|
* was issued
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
ao_wait(struct audio_output *ao)
|
||||||
|
{
|
||||||
|
while (true) {
|
||||||
|
unsigned delay = ao_plugin_delay(ao->plugin, ao->data);
|
||||||
|
if (delay == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
GTimeVal tv;
|
||||||
|
g_get_current_time(&tv);
|
||||||
|
g_time_val_add(&tv, delay * 1000);
|
||||||
|
g_cond_timed_wait(ao->cond, ao->mutex, &tv);
|
||||||
|
|
||||||
|
if (ao->command != AO_COMMAND_NONE)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
ao_chunk_data(struct audio_output *ao, const struct music_chunk *chunk,
|
ao_chunk_data(struct audio_output *ao, const struct music_chunk *chunk,
|
||||||
struct filter *replay_gain_filter,
|
struct filter *replay_gain_filter,
|
||||||
@ -414,6 +438,9 @@ ao_play_chunk(struct audio_output *ao, const struct music_chunk *chunk)
|
|||||||
while (size > 0 && ao->command == AO_COMMAND_NONE) {
|
while (size > 0 && ao->command == AO_COMMAND_NONE) {
|
||||||
size_t nbytes;
|
size_t nbytes;
|
||||||
|
|
||||||
|
if (!ao_wait(ao))
|
||||||
|
break;
|
||||||
|
|
||||||
g_mutex_unlock(ao->mutex);
|
g_mutex_unlock(ao->mutex);
|
||||||
nbytes = ao_plugin_play(ao->plugin, ao->data, data, size,
|
nbytes = ao_plugin_play(ao->plugin, ao->data, data, size,
|
||||||
&error);
|
&error);
|
||||||
@ -511,6 +538,9 @@ static void ao_pause(struct audio_output *ao)
|
|||||||
ao_command_finished(ao);
|
ao_command_finished(ao);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (!ao_wait(ao))
|
||||||
|
break;
|
||||||
|
|
||||||
g_mutex_unlock(ao->mutex);
|
g_mutex_unlock(ao->mutex);
|
||||||
ret = ao_plugin_pause(ao->plugin, ao->data);
|
ret = ao_plugin_pause(ao->plugin, ao->data);
|
||||||
g_mutex_lock(ao->mutex);
|
g_mutex_lock(ao->mutex);
|
||||||
|
@ -74,12 +74,12 @@ void timer_add(Timer *timer, int size)
|
|||||||
unsigned
|
unsigned
|
||||||
timer_delay(const Timer *timer)
|
timer_delay(const Timer *timer)
|
||||||
{
|
{
|
||||||
int64_t delay = timer->time - now();
|
int64_t delay = (timer->time - now()) / 1000;
|
||||||
if (delay < 0)
|
if (delay < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (delay > 1000 * 1000 * 1000)
|
if (delay > G_MAXINT)
|
||||||
return 1000 * 1000;
|
delay = G_MAXINT;
|
||||||
|
|
||||||
return delay / 1000;
|
return delay / 1000;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user