mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
node: add xrun callback
Let alsa emit xrun callbacks. Write the xrun stats to the activation area of the node so all clients can read it.
This commit is contained in:
parent
570575f052
commit
6ad4adc194
8 changed files with 80 additions and 15 deletions
|
|
@ -186,7 +186,8 @@ struct spa_node_events {
|
|||
|
||||
#define SPA_NODE_CALLBACK_READY 0
|
||||
#define SPA_NODE_CALLBACK_REUSE_BUFFER 1
|
||||
#define SPA_NODE_CALLBACK_NUM 2
|
||||
#define SPA_NODE_CALLBACK_XRUN 2
|
||||
#define SPA_NODE_CALLBACK_NUM 3
|
||||
|
||||
/** Node callbacks
|
||||
*
|
||||
|
|
@ -219,6 +220,19 @@ struct spa_node_callbacks {
|
|||
int (*reuse_buffer) (void *data,
|
||||
uint32_t port_id,
|
||||
uint32_t buffer_id);
|
||||
|
||||
/**
|
||||
* \param data user data
|
||||
* \param trigger the timestamp in microseconds when the xrun happened
|
||||
* \param delay the amount of microseconds of xrun.
|
||||
* \param info an object with extra info (NULL for now)
|
||||
*
|
||||
* The node has encountered an over or underrun
|
||||
*
|
||||
* The info contains an object with more information
|
||||
*/
|
||||
int (*xrun) (void *data, uint64_t trigger, uint64_t delay,
|
||||
struct spa_pod *info);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -117,10 +117,10 @@ static inline int spa_node_port_enum_params_sync(struct spa_node *node,
|
|||
spa_hook_list_call_simple(hooks, struct spa_node_events, \
|
||||
method, version, ##__VA_ARGS__)
|
||||
|
||||
#define spa_node_emit_info(hooks,i) spa_node_emit(hooks,info, 0, i)
|
||||
#define spa_node_emit_port_info(hooks,d,p,i) spa_node_emit(hooks,port_info, 0, d, p, i)
|
||||
#define spa_node_emit_result(hooks,s,r,t,res) spa_node_emit(hooks,result, 0, s, r, t, res)
|
||||
#define spa_node_emit_event(hooks,e) spa_node_emit(hooks,event, 0, e)
|
||||
#define spa_node_emit_info(hooks,...) spa_node_emit(hooks,info, 0, __VA_ARGS__)
|
||||
#define spa_node_emit_port_info(hooks,...) spa_node_emit(hooks,port_info, 0, __VA_ARGS__)
|
||||
#define spa_node_emit_result(hooks,...) spa_node_emit(hooks,result, 0, __VA_ARGS__)
|
||||
#define spa_node_emit_event(hooks,...) spa_node_emit(hooks,event, 0, __VA_ARGS__)
|
||||
|
||||
|
||||
#define spa_node_call(callbacks,method,version,...) \
|
||||
|
|
@ -131,8 +131,9 @@ static inline int spa_node_port_enum_params_sync(struct spa_node *node,
|
|||
_res; \
|
||||
})
|
||||
|
||||
#define spa_node_call_ready(hook,s) spa_node_call(hook, ready, 0, s)
|
||||
#define spa_node_call_reuse_buffer(hook,p,b) spa_node_call(hook, reuse_buffer, 0, p, b)
|
||||
#define spa_node_call_ready(hook,...) spa_node_call(hook, ready, 0, __VA_ARGS__)
|
||||
#define spa_node_call_reuse_buffer(hook,...) spa_node_call(hook, reuse_buffer, 0, __VA_ARGS__)
|
||||
#define spa_node_call_xrun(hook,...) spa_node_call(hook, xrun, 0, __VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
|
|
@ -542,17 +542,20 @@ static int alsa_recover(struct state *state, int err)
|
|||
case SND_PCM_STATE_XRUN:
|
||||
{
|
||||
struct timeval now, trigger, diff;
|
||||
uint64_t xrun, missing;
|
||||
uint64_t delay, missing;
|
||||
|
||||
snd_pcm_status_get_tstamp (status, &now);
|
||||
snd_pcm_status_get_trigger_tstamp (status, &trigger);
|
||||
timersub(&now, &trigger, &diff);
|
||||
|
||||
xrun = SPA_TIMEVAL_TO_USEC(&diff);
|
||||
missing = xrun * state->rate / SPA_USEC_PER_SEC;
|
||||
delay = SPA_TIMEVAL_TO_USEC(&diff);
|
||||
missing = delay * state->rate / SPA_USEC_PER_SEC;
|
||||
|
||||
spa_log_error(state->log, "%p: xrun of %"PRIu64" usec %"PRIu64" %f",
|
||||
state, xrun, missing, state->safety);
|
||||
state, delay, missing, state->safety);
|
||||
|
||||
spa_node_call_xrun(&state->callbacks,
|
||||
SPA_TIMEVAL_TO_USEC(&trigger), delay, NULL);
|
||||
|
||||
state->sample_count += missing ? missing : state->threshold;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -430,10 +430,17 @@ static int slave_reuse_buffer(void *data, uint32_t port_id, uint32_t buffer_id)
|
|||
return res;
|
||||
}
|
||||
|
||||
static int slave_xrun(void *data, uint64_t trigger, uint64_t delay, struct spa_pod *info)
|
||||
{
|
||||
struct impl *this = data;
|
||||
return spa_node_call_xrun(&this->callbacks, trigger, delay, info);
|
||||
}
|
||||
|
||||
static const struct spa_node_callbacks slave_node_callbacks = {
|
||||
SPA_VERSION_NODE_CALLBACKS,
|
||||
.ready = slave_ready,
|
||||
.reuse_buffer = slave_reuse_buffer,
|
||||
.xrun = slave_xrun,
|
||||
};
|
||||
|
||||
static int impl_node_add_listener(void *object,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue