mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	stream: add resample size to pw_time
Now that the resampler input size is set in the io_rate field when we start we can add it to the pw_time struct as well. This way we can know the required resampler input without having to dequeue a buffer. This can be handy when the stream is a driver and needs to know how much data to accumulate before starting the graph. See #3750
This commit is contained in:
		
							parent
							
								
									63e283f377
								
							
						
					
					
						commit
						1bbaf270f8
					
				
					 3 changed files with 24 additions and 19 deletions
				
			
		| 
						 | 
					@ -100,6 +100,7 @@ struct stream {
 | 
				
			||||||
	struct spa_io_buffers *io;
 | 
						struct spa_io_buffers *io;
 | 
				
			||||||
	struct spa_io_rate_match *rate_match;
 | 
						struct spa_io_rate_match *rate_match;
 | 
				
			||||||
	uint32_t rate_queued;
 | 
						uint32_t rate_queued;
 | 
				
			||||||
 | 
						uint64_t rate_requested;
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct spa_io_position *position;
 | 
							struct spa_io_position *position;
 | 
				
			||||||
	} rt;
 | 
						} rt;
 | 
				
			||||||
| 
						 | 
					@ -420,7 +421,7 @@ static struct buffer *get_buffer(struct pw_stream *stream, uint32_t id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline uint32_t update_requested(struct stream *impl)
 | 
					static inline uint32_t update_requested(struct stream *impl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t index, id, res = 0;
 | 
						uint32_t index, id;
 | 
				
			||||||
	struct buffer *buffer;
 | 
						struct buffer *buffer;
 | 
				
			||||||
	struct spa_io_rate_match *r = impl->rate_match;
 | 
						struct spa_io_rate_match *r = impl->rate_match;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -431,15 +432,11 @@ static inline uint32_t update_requested(struct stream *impl)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	id = impl->dequeued.ids[index & MASK_BUFFERS];
 | 
						id = impl->dequeued.ids[index & MASK_BUFFERS];
 | 
				
			||||||
	buffer = &impl->buffers[id];
 | 
						buffer = &impl->buffers[id];
 | 
				
			||||||
	if (r) {
 | 
						buffer->this.requested = r ? r->size : impl->quantum;
 | 
				
			||||||
		buffer->this.requested = r->size;
 | 
					
 | 
				
			||||||
		res = r->size > 0 ? 1 : 0;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		buffer->this.requested = impl->quantum;
 | 
					 | 
				
			||||||
		res = 1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	pw_log_trace_fp("%p: update buffer:%u req:%"PRIu64, impl, id, buffer->this.requested);
 | 
						pw_log_trace_fp("%p: update buffer:%u req:%"PRIu64, impl, id, buffer->this.requested);
 | 
				
			||||||
	return res;
 | 
					
 | 
				
			||||||
 | 
						return buffer->this.requested > 0 ? 1 : 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
| 
						 | 
					@ -643,8 +640,10 @@ static inline void copy_position(struct stream *impl, int64_t queued)
 | 
				
			||||||
		impl->time.queued = queued;
 | 
							impl->time.queued = queued;
 | 
				
			||||||
		impl->quantum = p->clock.duration;
 | 
							impl->quantum = p->clock.duration;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (SPA_LIKELY(impl->rate_match != NULL))
 | 
						if (SPA_LIKELY(impl->rate_match != NULL)) {
 | 
				
			||||||
		impl->rate_queued = impl->rate_match->delay;
 | 
							impl->rate_queued = impl->rate_match->delay;
 | 
				
			||||||
 | 
							impl->rate_requested = impl->rate_match->size;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	SPA_SEQ_WRITE(impl->seq);
 | 
						SPA_SEQ_WRITE(impl->seq);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -677,11 +676,11 @@ static int impl_send_command(void *object, const struct spa_command *command)
 | 
				
			||||||
				if (impl->io != NULL)
 | 
									if (impl->io != NULL)
 | 
				
			||||||
					impl->io->status = SPA_STATUS_NEED_DATA;
 | 
										impl->io->status = SPA_STATUS_NEED_DATA;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else if (!impl->process_rt && !impl->driving) {
 | 
								else {
 | 
				
			||||||
				copy_position(impl, impl->queued.incount);
 | 
									copy_position(impl, impl->queued.incount);
 | 
				
			||||||
				call_process(impl);
 | 
									if (!impl->process_rt && !impl->driving)
 | 
				
			||||||
 | 
										call_process(impl);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					 | 
				
			||||||
			stream_set_state(stream, PW_STREAM_STATE_STREAMING, 0, NULL);
 | 
								stream_set_state(stream, PW_STREAM_STATE_STREAMING, 0, NULL);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -2355,13 +2354,14 @@ int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
 | 
						struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
 | 
				
			||||||
	uintptr_t seq1, seq2;
 | 
						uintptr_t seq1, seq2;
 | 
				
			||||||
	uint32_t buffered, quantum, index;
 | 
						uint32_t buffered, quantum, index, requested;
 | 
				
			||||||
	int32_t avail_buffers;
 | 
						int32_t avail_buffers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		seq1 = SPA_SEQ_READ(impl->seq);
 | 
							seq1 = SPA_SEQ_READ(impl->seq);
 | 
				
			||||||
		memcpy(time, &impl->time, SPA_MIN(size, sizeof(struct pw_time)));
 | 
							memcpy(time, &impl->time, SPA_MIN(size, sizeof(struct pw_time)));
 | 
				
			||||||
		buffered = impl->rate_queued;
 | 
							buffered = impl->rate_queued;
 | 
				
			||||||
 | 
							requested = impl->rate_requested;
 | 
				
			||||||
		quantum = impl->quantum;
 | 
							quantum = impl->quantum;
 | 
				
			||||||
		seq2 = SPA_SEQ_READ(impl->seq);
 | 
							seq2 = SPA_SEQ_READ(impl->seq);
 | 
				
			||||||
	} while (!SPA_SEQ_READ_SUCCESS(seq1, seq2));
 | 
						} while (!SPA_SEQ_READ_SUCCESS(seq1, seq2));
 | 
				
			||||||
| 
						 | 
					@ -2382,8 +2382,10 @@ int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t
 | 
				
			||||||
		time->buffered = buffered;
 | 
							time->buffered = buffered;
 | 
				
			||||||
	if (size >= offsetof(struct pw_time, avail_buffers))
 | 
						if (size >= offsetof(struct pw_time, avail_buffers))
 | 
				
			||||||
		time->queued_buffers = impl->n_buffers - avail_buffers;
 | 
							time->queued_buffers = impl->n_buffers - avail_buffers;
 | 
				
			||||||
	if (size >= sizeof(struct pw_time))
 | 
						if (size >= offsetof(struct pw_time, requested))
 | 
				
			||||||
		time->avail_buffers = avail_buffers;
 | 
							time->avail_buffers = avail_buffers;
 | 
				
			||||||
 | 
						if (size >= sizeof(struct pw_time))
 | 
				
			||||||
 | 
							time->requested = requested;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_trace_fp("%p: %"PRIi64" %"PRIi64" %"PRIu64" %d/%d %"PRIu64" %"
 | 
						pw_log_trace_fp("%p: %"PRIi64" %"PRIi64" %"PRIu64" %d/%d %"PRIu64" %"
 | 
				
			||||||
			PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" %d/%d", stream,
 | 
								PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" %d/%d", stream,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -330,8 +330,11 @@ struct pw_time {
 | 
				
			||||||
	uint64_t buffered;		/**< for audio/raw streams, this contains the extra
 | 
						uint64_t buffered;		/**< for audio/raw streams, this contains the extra
 | 
				
			||||||
					  *  number of frames buffered in the resampler.
 | 
										  *  number of frames buffered in the resampler.
 | 
				
			||||||
					  *  Since 0.3.50. */
 | 
										  *  Since 0.3.50. */
 | 
				
			||||||
	uint32_t queued_buffers;	/**< The number of buffers that are queued. Since 0.3.50 */
 | 
						uint32_t queued_buffers;	/**< the number of buffers that are queued. Since 0.3.50 */
 | 
				
			||||||
	uint32_t avail_buffers;		/**< The number of buffers that can be dequeued. Since 0.3.50 */
 | 
						uint32_t avail_buffers;		/**< the number of buffers that can be dequeued. Since 0.3.50 */
 | 
				
			||||||
 | 
						uint64_t requested;		/**< for audio/raw playback streams, this contains the number of
 | 
				
			||||||
 | 
										  *  samples requested by the resampler to fill the current
 | 
				
			||||||
 | 
										  *  quantum. Since 1.1.0 */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <pipewire/port.h>
 | 
					#include <pipewire/port.h>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -932,11 +932,11 @@ static void do_print_delay(void *userdata, uint64_t expirations)
 | 
				
			||||||
	pw_stream_get_time_n(data->stream, &time, sizeof(time));
 | 
						pw_stream_get_time_n(data->stream, &time, sizeof(time));
 | 
				
			||||||
	printf("stream time: now:%"PRIi64" rate:%u/%u ticks:%"PRIu64
 | 
						printf("stream time: now:%"PRIi64" rate:%u/%u ticks:%"PRIu64
 | 
				
			||||||
			" delay:%"PRIi64" queued:%"PRIu64
 | 
								" delay:%"PRIi64" queued:%"PRIu64
 | 
				
			||||||
			" buffered:%"PRIi64" buffers:%u avail:%u\n",
 | 
								" buffered:%"PRIi64" buffers:%u avail:%u req:%"PRIu64"\n",
 | 
				
			||||||
		time.now,
 | 
							time.now,
 | 
				
			||||||
		time.rate.num, time.rate.denom,
 | 
							time.rate.num, time.rate.denom,
 | 
				
			||||||
		time.ticks, time.delay, time.queued, time.buffered,
 | 
							time.ticks, time.delay, time.queued, time.buffered,
 | 
				
			||||||
		time.queued_buffers, time.avail_buffers);
 | 
							time.queued_buffers, time.avail_buffers, time.requested);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue