/* * Copyright (c) 2019, Linaro Limited * * SPDX-License-Identifier: Apache-2.0 */ #include #include #if defined(CONFIG_VIDEO_BUFFER_USE_SHARED_MULTI_HEAP) #include #define VIDEO_COMMON_HEAP_ALLOC(align, size, timeout) \ shared_multi_heap_aligned_alloc(CONFIG_VIDEO_BUFFER_SMH_ATTRIBUTE, align, size) #define VIDEO_COMMON_FREE(block) shared_multi_heap_free(block) #else K_HEAP_DEFINE(video_buffer_pool, CONFIG_VIDEO_BUFFER_POOL_SZ_MAX*CONFIG_VIDEO_BUFFER_POOL_NUM_MAX); #define VIDEO_COMMON_HEAP_ALLOC(align, size, timeout) \ k_heap_aligned_alloc(&video_buffer_pool, align, size, timeout); #define VIDEO_COMMON_FREE(block) k_heap_free(&video_buffer_pool, block) #endif static struct video_buffer video_buf[CONFIG_VIDEO_BUFFER_POOL_NUM_MAX]; struct mem_block { void *data; }; 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 *vbuf = NULL; struct mem_block *block; int i; /* find available video buffer */ for (i = 0; i < ARRAY_SIZE(video_buf); i++) { if (video_buf[i].buffer == NULL) { vbuf = &video_buf[i]; block = &video_block[i]; break; } } if (vbuf == NULL) { return NULL; } /* Alloc buffer memory */ block->data = VIDEO_COMMON_HEAP_ALLOC(align, size, K_FOREVER); if (block->data == NULL) { return NULL; } vbuf->buffer = block->data; vbuf->size = size; vbuf->bytesused = 0; return vbuf; } struct video_buffer *video_buffer_alloc(size_t size) { return video_buffer_aligned_alloc(size, sizeof(void *)); } void video_buffer_release(struct video_buffer *vbuf) { struct mem_block *block = NULL; int i; /* vbuf to block */ for (i = 0; i < ARRAY_SIZE(video_block); i++) { if (video_block[i].data == vbuf->buffer) { block = &video_block[i]; break; } } vbuf->buffer = NULL; if (block) { VIDEO_COMMON_FREE(block->data); } }