drivers: video: Add timeout tovideo_buffer_alloc

This PR fixes a blocking call to video_buffer_alloc in case of memory
shortage by addign a timeout parameter to the API.

Signed-off-by: Armin Kessler <ake@espros.com>
This commit is contained in:
Armin Kessler 2024-10-31 09:44:22 +01:00 committed by Benjamin Cabé
parent adaa87a69d
commit 1baf93b1d1
7 changed files with 16 additions and 10 deletions

View file

@ -75,6 +75,9 @@ Device Drivers and Devicetree
* :c:struct:`adc_driver_api` * :c:struct:`adc_driver_api`
* The :c:func:`video_buffer_alloc` and :c:func:`video_buffer_aligned_alloc` functions in the
video API now take an additional timeout parameter.
ADC ADC
=== ===

View file

@ -31,7 +31,7 @@ struct mem_block {
static struct mem_block video_block[CONFIG_VIDEO_BUFFER_POOL_NUM_MAX]; static struct mem_block video_block[CONFIG_VIDEO_BUFFER_POOL_NUM_MAX];
struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align) struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align, k_timeout_t timeout)
{ {
struct video_buffer *vbuf = NULL; struct video_buffer *vbuf = NULL;
struct mem_block *block; struct mem_block *block;
@ -51,7 +51,7 @@ struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align)
} }
/* Alloc buffer memory */ /* Alloc buffer memory */
block->data = VIDEO_COMMON_HEAP_ALLOC(align, size, K_FOREVER); block->data = VIDEO_COMMON_HEAP_ALLOC(align, size, timeout);
if (block->data == NULL) { if (block->data == NULL) {
return NULL; return NULL;
} }
@ -63,9 +63,9 @@ struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align)
return vbuf; return vbuf;
} }
struct video_buffer *video_buffer_alloc(size_t size) struct video_buffer *video_buffer_alloc(size_t size, k_timeout_t timeout)
{ {
return video_buffer_aligned_alloc(size, sizeof(void *)); return video_buffer_aligned_alloc(size, sizeof(void *), timeout);
} }
void video_buffer_release(struct video_buffer *vbuf) void video_buffer_release(struct video_buffer *vbuf)

View file

@ -732,19 +732,21 @@ static inline int video_set_signal(const struct device *dev, enum video_endpoint
* *
* @param size Size of the video buffer (in bytes). * @param size Size of the video buffer (in bytes).
* @param align Alignment of the requested memory, must be a power of two. * @param align Alignment of the requested memory, must be a power of two.
* @param timeout Timeout duration or K_NO_WAIT
* *
* @retval pointer to allocated video buffer * @retval pointer to allocated video buffer
*/ */
struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align); struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align, k_timeout_t timeout);
/** /**
* @brief Allocate video buffer. * @brief Allocate video buffer.
* *
* @param size Size of the video buffer (in bytes). * @param size Size of the video buffer (in bytes).
* @param timeout Timeout duration or K_NO_WAIT
* *
* @retval pointer to allocated video buffer * @retval pointer to allocated video buffer
*/ */
struct video_buffer *video_buffer_alloc(size_t size); struct video_buffer *video_buffer_alloc(size_t size, k_timeout_t timeout);
/** /**
* @brief Release a video buffer. * @brief Release a video buffer.

View file

@ -211,7 +211,8 @@ int main(void)
* For some hardwares, such as the PxP used on i.MX RT1170 to do image rotation, * For some hardwares, such as the PxP used on i.MX RT1170 to do image rotation,
* buffer alignment is needed in order to achieve the best performance * buffer alignment is needed in order to achieve the best performance
*/ */
buffers[i] = video_buffer_aligned_alloc(bsize, CONFIG_VIDEO_BUFFER_POOL_ALIGN); buffers[i] = video_buffer_aligned_alloc(bsize, CONFIG_VIDEO_BUFFER_POOL_ALIGN,
K_FOREVER);
if (buffers[i] == NULL) { if (buffers[i] == NULL) {
LOG_ERR("Unable to alloc video buffer"); LOG_ERR("Unable to alloc video buffer");
return 0; return 0;

View file

@ -97,7 +97,7 @@ int main(void)
/* Alloc video buffers and enqueue for capture */ /* Alloc video buffers and enqueue for capture */
for (i = 0; i < ARRAY_SIZE(buffers); i++) { for (i = 0; i < ARRAY_SIZE(buffers); i++) {
buffers[i] = video_buffer_alloc(bsize); buffers[i] = video_buffer_alloc(bsize, K_FOREVER);
if (buffers[i] == NULL) { if (buffers[i] == NULL) {
LOG_ERR("Unable to alloc video buffer"); LOG_ERR("Unable to alloc video buffer");
return 0; return 0;

View file

@ -105,7 +105,7 @@ int main(void)
/* Alloc Buffers */ /* Alloc Buffers */
for (i = 0; i < ARRAY_SIZE(buffers); i++) { for (i = 0; i < ARRAY_SIZE(buffers); i++) {
buffers[i] = video_buffer_alloc(fmt.pitch * fmt.height); buffers[i] = video_buffer_alloc(fmt.pitch * fmt.height, K_FOREVER);
if (buffers[i] == NULL) { if (buffers[i] == NULL) {
LOG_ERR("Unable to alloc video buffer"); LOG_ERR("Unable to alloc video buffer");
return 0; return 0;

View file

@ -157,7 +157,7 @@ ZTEST(video_common, test_video_vbuf)
zexpect_ok(video_set_format(rx_dev, VIDEO_EP_OUT, &fmt)); zexpect_ok(video_set_format(rx_dev, VIDEO_EP_OUT, &fmt));
/* Allocate a buffer, assuming prj.conf gives enough memory for it */ /* Allocate a buffer, assuming prj.conf gives enough memory for it */
vbuf = video_buffer_alloc(fmt.pitch * fmt.height); vbuf = video_buffer_alloc(fmt.pitch * fmt.height, K_FOREVER);
zexpect_not_null(vbuf); zexpect_not_null(vbuf);
/* Start the virtual hardware */ /* Start the virtual hardware */