#include "FreeRTOS.h" #include "board.h" #include "sysinfo.h" #include "chip.h" typedef enum { VBUF_STATUS_FREE = 0, VBUF_STATUS_USED, VBUF_STATUS_RENDERED, } VIDEO_BUFFER_STATUS; typedef struct { uint32_t addr; int status; }VideoBufInfo; static SemaphoreHandle_t vdisbuf_mutex = NULL; static VideoBufInfo vdisbufs[VIDEO_DISPLAY_BUF_NUM] = {0}; void VideoDisplayBufInit(void) { int i; vdisbuf_mutex = xSemaphoreCreateRecursiveMutex(); for (i = 0; i < VIDEO_DISPLAY_BUF_NUM; i++) { vdisbufs[i].addr = (uint32_t)pvPortMalloc(VIDEO_DISPLAY_WIDTH * VIDEO_DISPLAY_HEIGHT * 2); vdisbufs[i].status = VBUF_STATUS_FREE; } } int xVideoDisplayBufTake(uint32_t xTicksToWait) { return xSemaphoreTakeRecursive(vdisbuf_mutex, xTicksToWait); } void vVideoDisplayBufGive(void) { xSemaphoreGiveRecursive(vdisbuf_mutex); } uint32_t ulVideoDisplayBufGet(void) { uint32_t bufaddr = 0; int i; xSemaphoreTakeRecursive(vdisbuf_mutex, portMAX_DELAY); for (i = 0; i < VIDEO_DISPLAY_BUF_NUM; i++) { if (vdisbufs[i].status == VBUF_STATUS_FREE) { bufaddr = vdisbufs[i].addr; vdisbufs[i].status = VBUF_STATUS_USED; break; } } xSemaphoreGiveRecursive(vdisbuf_mutex); configASSERT(bufaddr != 0); return bufaddr; } uint32_t ulVideoDisplayBufGetSize(void) { return VIDEO_DISPLAY_WIDTH * VIDEO_DISPLAY_HEIGHT * 2; } void vVideoDisplayBufRender(uint32_t buf_addr) { int i, j; xSemaphoreTakeRecursive(vdisbuf_mutex, portMAX_DELAY); for (i = 0; i < VIDEO_DISPLAY_BUF_NUM; i++) { if (vdisbufs[i].addr == buf_addr) { for (j = 0; j < VIDEO_DISPLAY_BUF_NUM; j++) { if (vdisbufs[j].status == VBUF_STATUS_RENDERED) vdisbufs[j].status = VBUF_STATUS_FREE; } vdisbufs[i].status = VBUF_STATUS_RENDERED; break; } } xSemaphoreGiveRecursive(vdisbuf_mutex); } void vVideoDisplayBufFree(uint32_t buf_addr) { int i; xSemaphoreTakeRecursive(vdisbuf_mutex, portMAX_DELAY); for (i = 0; i < VIDEO_DISPLAY_BUF_NUM; i++) { if (vdisbufs[i].addr == buf_addr) { vdisbufs[i].status = VBUF_STATUS_FREE; break; } } xSemaphoreGiveRecursive(vdisbuf_mutex); } unsigned int ulVideoDisplayGetBufferAddr(int index) { configASSERT(index < VIDEO_DISPLAY_BUF_NUM); return vdisbufs[index].addr; }