mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	spa: libcamera: source: allocBuffers(): restore on failure
Undo the allocation and clear the requests if a failure is encountered
in order to leave things in a known state.
(cherry picked from commit 348e703be0)
			
			
This commit is contained in:
		
							parent
							
								
									b28eb20c1f
								
							
						
					
					
						commit
						98842d50cf
					
				
					 1 changed files with 36 additions and 25 deletions
				
			
		| 
						 | 
				
			
			@ -278,18 +278,42 @@ int spa_libcamera_buffer_recycle(struct impl *impl, struct port *port, uint32_t
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void freeBuffers(struct impl *impl, struct port *port)
 | 
			
		||||
{
 | 
			
		||||
	impl->requestPool.clear();
 | 
			
		||||
	std::ignore = impl->allocator->free(port->streamConfig.stream());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[[nodiscard]]
 | 
			
		||||
std::size_t count_unique_fds(libcamera::Span<const libcamera::FrameBuffer::Plane> planes)
 | 
			
		||||
{
 | 
			
		||||
	std::size_t c = 0;
 | 
			
		||||
	int fd = -1;
 | 
			
		||||
 | 
			
		||||
	for (const auto& plane : planes) {
 | 
			
		||||
		const int current_fd = plane.fd.get();
 | 
			
		||||
		if (current_fd >= 0 && current_fd != fd) {
 | 
			
		||||
			c += 1;
 | 
			
		||||
			fd = current_fd;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int allocBuffers(struct impl *impl, struct port *port, unsigned int count)
 | 
			
		||||
{
 | 
			
		||||
	libcamera::Stream *stream = port->streamConfig.stream();
 | 
			
		||||
	int res;
 | 
			
		||||
 | 
			
		||||
	if ((res = impl->allocator->allocate(port->streamConfig.stream())) < 0)
 | 
			
		||||
	if ((res = impl->allocator->allocate(stream)) < 0)
 | 
			
		||||
		return res;
 | 
			
		||||
 | 
			
		||||
	for (unsigned int i = 0; i < count; i++) {
 | 
			
		||||
		std::unique_ptr<Request> request = impl->camera->createRequest(i);
 | 
			
		||||
		if (!request) {
 | 
			
		||||
			impl->requestPool.clear();
 | 
			
		||||
			return -ENOMEM;
 | 
			
		||||
			res = -ENOMEM;
 | 
			
		||||
			goto err;
 | 
			
		||||
		}
 | 
			
		||||
		impl->requestPool.push_back(std::move(request));
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -299,33 +323,20 @@ int allocBuffers(struct impl *impl, struct port *port, unsigned int count)
 | 
			
		|||
	 * video frame has to be addressed using more than one memory.
 | 
			
		||||
	 * address. Therefore, need calculate the number of discontiguous
 | 
			
		||||
	 * memory and allocate the specified amount of memory */
 | 
			
		||||
	Stream *stream = impl->config->at(0).stream();
 | 
			
		||||
	const std::vector<std::unique_ptr<FrameBuffer>> &bufs =
 | 
			
		||||
			impl->allocator->buffers(stream);
 | 
			
		||||
	const std::vector<libcamera::FrameBuffer::Plane> &planes = bufs[0]->planes();
 | 
			
		||||
	int fd = -1;
 | 
			
		||||
	uint32_t buffers_blocks = 0;
 | 
			
		||||
 | 
			
		||||
	for (const FrameBuffer::Plane &plane : planes) {
 | 
			
		||||
		const int current_fd = plane.fd.get();
 | 
			
		||||
		if (current_fd >= 0 && current_fd != fd) {
 | 
			
		||||
			buffers_blocks += 1;
 | 
			
		||||
			fd = current_fd;
 | 
			
		||||
		}
 | 
			
		||||
	port->buffers_blocks = count_unique_fds(impl->allocator->buffers(stream).front()->planes());
 | 
			
		||||
	if (port->buffers_blocks <= 0) {
 | 
			
		||||
		res = -ENOBUFS;
 | 
			
		||||
		goto err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (buffers_blocks > 0) {
 | 
			
		||||
		port->buffers_blocks = buffers_blocks;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
err:
 | 
			
		||||
	freeBuffers(impl, port);
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void freeBuffers(struct impl *impl, struct port *port)
 | 
			
		||||
{
 | 
			
		||||
	impl->requestPool.clear();
 | 
			
		||||
	impl->allocator->free(port->streamConfig.stream());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int spa_libcamera_clear_buffers(struct impl *impl, struct port *port)
 | 
			
		||||
{
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue