diff --git a/src/pipewire/filter.c b/src/pipewire/filter.c index 1a8d34dff..4c774a9d3 100644 --- a/src/pipewire/filter.c +++ b/src/pipewire/filter.c @@ -2064,6 +2064,12 @@ bool pw_filter_is_driving(struct pw_filter *filter) return filter->node->driving; } +SPA_EXPORT +bool pw_filter_is_lazy(struct pw_filter *filter) +{ + return filter->node->lazy; +} + static int do_trigger_process(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data) diff --git a/src/pipewire/filter.h b/src/pipewire/filter.h index 2f4b2267f..701c4481b 100644 --- a/src/pipewire/filter.h +++ b/src/pipewire/filter.h @@ -249,6 +249,10 @@ int pw_filter_flush(struct pw_filter *filter, bool drain); * available (output) or needed (input). Since 0.3.66 */ bool pw_filter_is_driving(struct pw_filter *filter); +/** Check if the graph is using lazy scheduling. + * Since 1.2.7 */ +bool pw_filter_is_lazy(struct pw_filter *filter); + /** Trigger a push/pull on the filter. One iteration of the graph will * be scheduled and process() will be called. Since 0.3.66 */ int pw_filter_trigger_process(struct pw_filter *filter); diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 0abc41904..874aa3dc8 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -2523,6 +2523,12 @@ bool pw_stream_is_driving(struct pw_stream *stream) return stream->node->driving; } +SPA_EXPORT +bool pw_stream_is_lazy(struct pw_stream *stream) +{ + return stream->node->lazy; +} + static int do_trigger_driver(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data) diff --git a/src/pipewire/stream.h b/src/pipewire/stream.h index 60967daa3..b1c8c6cd0 100644 --- a/src/pipewire/stream.h +++ b/src/pipewire/stream.h @@ -569,16 +569,33 @@ int pw_stream_flush(struct pw_stream *stream, bool drain); * available (output) or needed (input). Since 0.3.34 */ bool pw_stream_is_driving(struct pw_stream *stream); +/** Check if the graph is using lazy scheduling. If the stream is + * driving according to \ref pw_stream_is_driving(), then it should + * consider taking into account the RequestProcess commands when + * driving the graph. + * + * If the stream is not driving, it should send out RequestProcess + * events with \ref pw_stream_emit_event() or indirectly with + * \ref pw_stream_trigger_process() to suggest a new graph cycle + * to the driver. + * + * It is not a requirement that all RequestProcess events/commands + * need to start a graph cycle. + * Since 1.2.7 */ +bool pw_stream_is_lazy(struct pw_stream *stream); + /** Trigger a push/pull on the stream. One iteration of the graph will - * be scheduled. If it successfully finishes, process() will be called. - * It is possible for the graph iteration to not finish, so + * be scheduled when the stream is driving according to + * \ref pw_stream_is_driving(). If it successfully finishes, process() + * will be called and the trigger_done event will be emitted. It is + * possible for the graph iteration to not finish, so * pw_stream_trigger_process() needs to be called again even if process() - * is not called. + * and trigger_done is not called. * * If there is a deadline after which the stream will have xrun, * pw_stream_trigger_process() should be called then, whether or not - * process() has been called. Sound hardware will xrun if there is - * any delay in audio processing, so the ALSA plugin triggers the + * process()/trigger_done has been called. Sound hardware will xrun if + * there is any delay in audio processing, so the ALSA plugin triggers the * graph every quantum to ensure audio keeps flowing. Drivers that * do not have a deadline, such as the freewheel driver, should * use a timeout to ensure that forward progress keeps being made. @@ -586,6 +603,13 @@ bool pw_stream_is_driving(struct pw_stream *stream); * the graph is taking 3x longer than normal, it is likely that it * is hung and should be retriggered. * + * Streams that are not drivers according to \ref pw_stream_is_driving() + * can also call this method. The result is that a RequestProcess event + * is sent to the driver. If the graph is lazy scheduling according to + * \ref pw_stream_is_lazy(), this might result in a graph cycle by the + * driver. If the graph is not lazy scheduling and the stream is not a + * driver, this method will have no effect. + * * Since 0.3.34 */ int pw_stream_trigger_process(struct pw_stream *stream);