mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	stream: Detect if we are driving or not
We need to check the position vs the clock to see if we are currently driving the graph. We can only call the node ready callback when we are actually driving the graph.
This commit is contained in:
		
							parent
							
								
									5da2081a4b
								
							
						
					
					
						commit
						42e0b520aa
					
				
					 1 changed files with 19 additions and 16 deletions
				
			
		| 
						 | 
					@ -112,6 +112,7 @@ struct stream {
 | 
				
			||||||
	struct spa_hook_list hooks;
 | 
						struct spa_hook_list hooks;
 | 
				
			||||||
	struct spa_callbacks callbacks;
 | 
						struct spa_callbacks callbacks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct spa_io_clock *clock;
 | 
				
			||||||
	struct spa_io_position *position;
 | 
						struct spa_io_position *position;
 | 
				
			||||||
	struct spa_io_buffers *io;
 | 
						struct spa_io_buffers *io;
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
| 
						 | 
					@ -164,6 +165,7 @@ struct stream {
 | 
				
			||||||
	unsigned int allow_mlock:1;
 | 
						unsigned int allow_mlock:1;
 | 
				
			||||||
	unsigned int warn_mlock:1;
 | 
						unsigned int warn_mlock:1;
 | 
				
			||||||
	unsigned int process_rt:1;
 | 
						unsigned int process_rt:1;
 | 
				
			||||||
 | 
						unsigned int driving:1;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int get_param_index(uint32_t id)
 | 
					static int get_param_index(uint32_t id)
 | 
				
			||||||
| 
						 | 
					@ -433,15 +435,25 @@ static int impl_set_io(void *object, uint32_t id, void *data, size_t size)
 | 
				
			||||||
			spa_debug_type_find_name(spa_type_io, id), data, size);
 | 
								spa_debug_type_find_name(spa_type_io, id), data, size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch(id) {
 | 
						switch(id) {
 | 
				
			||||||
 | 
						case SPA_IO_Clock:
 | 
				
			||||||
 | 
							if (data && size >= sizeof(struct spa_io_clock))
 | 
				
			||||||
 | 
								impl->clock = data;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								impl->clock = NULL;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	case SPA_IO_Position:
 | 
						case SPA_IO_Position:
 | 
				
			||||||
		if (data && size >= sizeof(struct spa_io_position))
 | 
							if (data && size >= sizeof(struct spa_io_position))
 | 
				
			||||||
			impl->position = data;
 | 
								impl->position = data;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			impl->position = NULL;
 | 
								impl->position = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pw_loop_invoke(impl->context->data_loop,
 | 
							pw_loop_invoke(impl->context->data_loop,
 | 
				
			||||||
				do_set_position, 1, NULL, 0, true, impl);
 | 
									do_set_position, 1, NULL, 0, true, impl);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						impl->driving = impl->clock && impl->position && impl->position->clock.id == impl->clock->id;
 | 
				
			||||||
	pw_stream_emit_io_changed(stream, id, data, size);
 | 
						pw_stream_emit_io_changed(stream, id, data, size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -938,8 +950,7 @@ again:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	copy_position(impl, impl->queued.outcount);
 | 
						copy_position(impl, impl->queued.outcount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!impl->draining &&
 | 
						if (!impl->draining && !impl->driving) {
 | 
				
			||||||
	    !SPA_FLAG_IS_SET(impl->flags, PW_STREAM_FLAG_DRIVER)) {
 | 
					 | 
				
			||||||
		/* we're not draining, not a driver check if we need to get
 | 
							/* we're not draining, not a driver check if we need to get
 | 
				
			||||||
		 * more buffers */
 | 
							 * more buffers */
 | 
				
			||||||
		if (!impl->process_rt) {
 | 
							if (!impl->process_rt) {
 | 
				
			||||||
| 
						 | 
					@ -1993,7 +2004,7 @@ int pw_stream_get_time(struct pw_stream *stream, struct pw_time *time)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
do_process(struct spa_loop *loop,
 | 
					do_trigger(struct spa_loop *loop,
 | 
				
			||||||
                 bool async, uint32_t seq, const void *data, size_t size, void *user_data)
 | 
					                 bool async, uint32_t seq, const void *data, size_t size, void *user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct stream *impl = user_data;
 | 
						struct stream *impl = user_data;
 | 
				
			||||||
| 
						 | 
					@ -2001,16 +2012,6 @@ do_process(struct spa_loop *loop,
 | 
				
			||||||
	return spa_node_call_ready(&impl->callbacks, res);
 | 
						return spa_node_call_ready(&impl->callbacks, res);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int call_trigger(struct stream *impl)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int res = 0;
 | 
					 | 
				
			||||||
	if (SPA_FLAG_IS_SET(impl->flags, PW_STREAM_FLAG_DRIVER)) {
 | 
					 | 
				
			||||||
		res = pw_loop_invoke(impl->context->data_loop,
 | 
					 | 
				
			||||||
			do_process, 1, NULL, 0, false, impl);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return res;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SPA_EXPORT
 | 
					SPA_EXPORT
 | 
				
			||||||
struct pw_buffer *pw_stream_dequeue_buffer(struct pw_stream *stream)
 | 
					struct pw_buffer *pw_stream_dequeue_buffer(struct pw_stream *stream)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -2052,9 +2053,11 @@ int pw_stream_queue_buffer(struct pw_stream *stream, struct pw_buffer *buffer)
 | 
				
			||||||
	if ((res = push_queue(impl, &impl->queued, b)) < 0)
 | 
						if ((res = push_queue(impl, &impl->queued, b)) < 0)
 | 
				
			||||||
		return res;
 | 
							return res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (impl->direction == SPA_DIRECTION_OUTPUT)
 | 
						if (impl->direction == SPA_DIRECTION_OUTPUT &&
 | 
				
			||||||
		res = call_trigger(impl);
 | 
						    impl->driving) {
 | 
				
			||||||
 | 
							res = pw_loop_invoke(impl->context->data_loop,
 | 
				
			||||||
 | 
								do_trigger, 1, NULL, 0, false, impl);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue