mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #861 from kwagyeman/kwabena/make_frame_buffer_respect_fb_alloc
Frame buffer respects fb alloc now
This commit is contained in:
commit
4638f2bb3b
@ -31,6 +31,11 @@ static char *fb_alloc_min_address()
|
|||||||
return (char *) (framebuffer_get_buffer() + framebuffer_get_frame_size());
|
return (char *) (framebuffer_get_buffer() + framebuffer_get_frame_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *fb_alloc_stack_pointer()
|
||||||
|
{
|
||||||
|
return pointer;
|
||||||
|
}
|
||||||
|
|
||||||
__weak NORETURN void fb_alloc_fail()
|
__weak NORETURN void fb_alloc_fail()
|
||||||
{
|
{
|
||||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError,
|
nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError,
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#define FB_ALLOC_NO_HINT 0
|
#define FB_ALLOC_NO_HINT 0
|
||||||
#define FB_ALLOC_PREFER_SPEED 1
|
#define FB_ALLOC_PREFER_SPEED 1
|
||||||
#define FB_ALLOC_PREFER_SIZE 2
|
#define FB_ALLOC_PREFER_SIZE 2
|
||||||
|
char *fb_alloc_stack_pointer();
|
||||||
void fb_alloc_fail();
|
void fb_alloc_fail();
|
||||||
void fb_alloc_init0();
|
void fb_alloc_init0();
|
||||||
uint32_t fb_avail();
|
uint32_t fb_avail();
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
#define CONSERVATIVE_JPEG_BUF_SIZE (OMV_JPEG_BUF_SIZE-64)
|
#define CONSERVATIVE_JPEG_BUF_SIZE (OMV_JPEG_BUF_SIZE-64)
|
||||||
|
|
||||||
extern char _fb_base;
|
extern char _fb_base;
|
||||||
extern char _fballoc;
|
|
||||||
framebuffer_t *framebuffer = (framebuffer_t *) &_fb_base;
|
framebuffer_t *framebuffer = (framebuffer_t *) &_fb_base;
|
||||||
|
|
||||||
extern char _jpeg_buf;
|
extern char _jpeg_buf;
|
||||||
@ -200,32 +199,19 @@ int32_t framebuffer_get_depth()
|
|||||||
|
|
||||||
uint32_t framebuffer_get_frame_size()
|
uint32_t framebuffer_get_frame_size()
|
||||||
{
|
{
|
||||||
switch (framebuffer->bpp) {
|
image_t img;
|
||||||
case -1: {
|
framebuffer_initialize_image(&img);
|
||||||
// Invalid frame.
|
return image_size(&img);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case IMAGE_BPP_BINARY: {
|
|
||||||
return ((framebuffer->w + UINT32_T_MASK) >> UINT32_T_SHIFT) * framebuffer->h;
|
|
||||||
}
|
|
||||||
case IMAGE_BPP_GRAYSCALE: {
|
|
||||||
return (framebuffer->w * framebuffer->h) * sizeof(uint8_t);
|
|
||||||
}
|
|
||||||
case IMAGE_BPP_RGB565: {
|
|
||||||
return (framebuffer->w * framebuffer->h) * sizeof(uint16_t);
|
|
||||||
}
|
|
||||||
case IMAGE_BPP_BAYER: {
|
|
||||||
return framebuffer->w * framebuffer->h;
|
|
||||||
}
|
|
||||||
default: { // JPEG
|
|
||||||
return framebuffer->bpp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t framebuffer_get_buffer_size()
|
uint32_t framebuffer_get_buffer_size()
|
||||||
{
|
{
|
||||||
return &_fballoc - (char *) framebuffer->pixels;
|
uint32_t size = (uint32_t) (fb_alloc_stack_pointer() - ((char *) framebuffer->pixels));
|
||||||
|
// We don't want to give all of the frame buffer RAM to the frame buffer. So, we will limit the
|
||||||
|
// maximum amount of RAM we return.
|
||||||
|
size = IM_MIN(size, OMV_RAW_BUF_SIZE);
|
||||||
|
// Needs to be a multiple of 32 for DMA transfers...
|
||||||
|
return (size / 32) * 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *framebuffer_get_buffer()
|
uint8_t *framebuffer_get_buffer()
|
||||||
|
|||||||
@ -64,7 +64,8 @@ int32_t framebuffer_get_depth();
|
|||||||
// otherwise return 0 if the framebuffer is unintialized or invalid (e.g. first frame).
|
// otherwise return 0 if the framebuffer is unintialized or invalid (e.g. first frame).
|
||||||
uint32_t framebuffer_get_frame_size();
|
uint32_t framebuffer_get_frame_size();
|
||||||
|
|
||||||
// Return the max frame size that fits the framebuffer (i.e OMV_RAW_BUF_SIZE - sizeof(framebuffer_t))
|
// Return the max frame size that fits the framebuffer
|
||||||
|
// (i.e OMV_RAW_BUF_SIZE - sizeof(framebuffer_t))
|
||||||
uint32_t framebuffer_get_buffer_size();
|
uint32_t framebuffer_get_buffer_size();
|
||||||
|
|
||||||
// Return the current buffer address.
|
// Return the current buffer address.
|
||||||
|
|||||||
@ -475,7 +475,7 @@ static int sensor_check_buffsize(sensor_t *sensor)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((MAIN_FB()->w * MAIN_FB()->h * bpp) > OMV_RAW_BUF_SIZE) {
|
if ((MAIN_FB()->w * MAIN_FB()->h * bpp) > framebuffer_get_buffer_size()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -550,10 +550,11 @@ int sensor_set_pixformat(pixformat_t pixformat)
|
|||||||
// This code is explicitly here to allow users to set the resolution to RGB565 and have it
|
// This code is explicitly here to allow users to set the resolution to RGB565 and have it
|
||||||
// switch to BAYER only once even though they are setting the resolution to RGB565 repeatedly
|
// switch to BAYER only once even though they are setting the resolution to RGB565 repeatedly
|
||||||
// in a loop. Only RGB565->BAYER has this problem and needs this fix because of sensor_check_buffsize().
|
// in a loop. Only RGB565->BAYER has this problem and needs this fix because of sensor_check_buffsize().
|
||||||
|
uint32_t size = framebuffer_get_buffer_size();
|
||||||
if ((sensor.pixformat == PIXFORMAT_BAYER)
|
if ((sensor.pixformat == PIXFORMAT_BAYER)
|
||||||
&& (pixformat == PIXFORMAT_RGB565)
|
&& (pixformat == PIXFORMAT_RGB565)
|
||||||
&& (MAIN_FB()->u * MAIN_FB()->v * 2 > OMV_RAW_BUF_SIZE)
|
&& (MAIN_FB()->u * MAIN_FB()->v * 2 > size)
|
||||||
&& (MAIN_FB()->u * MAIN_FB()->v * 1 <= OMV_RAW_BUF_SIZE)) {
|
&& (MAIN_FB()->u * MAIN_FB()->v * 1 <= size)) {
|
||||||
// No change
|
// No change
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -921,6 +922,7 @@ void DCMI_VsyncExtiCallback()
|
|||||||
// within the RAM we have onboard the system.
|
// within the RAM we have onboard the system.
|
||||||
static void sensor_check_buffsize()
|
static void sensor_check_buffsize()
|
||||||
{
|
{
|
||||||
|
uint32_t size = framebuffer_get_buffer_size();
|
||||||
uint32_t bpp;
|
uint32_t bpp;
|
||||||
|
|
||||||
switch (sensor.pixformat) {
|
switch (sensor.pixformat) {
|
||||||
@ -938,7 +940,7 @@ static void sensor_check_buffsize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MAIN_FB() fits, we are done.
|
// MAIN_FB() fits, we are done.
|
||||||
if ((MAIN_FB()->u * MAIN_FB()->v * bpp) <= OMV_RAW_BUF_SIZE) {
|
if ((MAIN_FB()->u * MAIN_FB()->v * bpp) <= size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -948,7 +950,7 @@ static void sensor_check_buffsize()
|
|||||||
bpp = 1;
|
bpp = 1;
|
||||||
|
|
||||||
// MAIN_FB() fits, we are done (bpp is 1).
|
// MAIN_FB() fits, we are done (bpp is 1).
|
||||||
if (MAIN_FB()->u * MAIN_FB()->v <= OMV_RAW_BUF_SIZE) {
|
if (MAIN_FB()->u * MAIN_FB()->v <= size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -995,7 +997,7 @@ static void sensor_check_buffsize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crop the frame buffer while keeping the aspect ratio and keeping the width/height even.
|
// Crop the frame buffer while keeping the aspect ratio and keeping the width/height even.
|
||||||
while (((MAIN_FB()->u * MAIN_FB()->v * bpp) > OMV_RAW_BUF_SIZE) || (MAIN_FB()->u % 2) || (MAIN_FB()->v % 2)) {
|
while (((MAIN_FB()->u * MAIN_FB()->v * bpp) > size) || (MAIN_FB()->u % 2) || (MAIN_FB()->v % 2)) {
|
||||||
MAIN_FB()->u -= u_sub;
|
MAIN_FB()->u -= u_sub;
|
||||||
MAIN_FB()->v -= v_sub;
|
MAIN_FB()->v -= v_sub;
|
||||||
}
|
}
|
||||||
@ -1109,7 +1111,7 @@ void DCMI_DMAConvCpltUser(uint32_t addr)
|
|||||||
//
|
//
|
||||||
uint16_t size = __REV16(*src16);
|
uint16_t size = __REV16(*src16);
|
||||||
// Prevent a buffer overflow when writing the jpeg data.
|
// Prevent a buffer overflow when writing the jpeg data.
|
||||||
if (offset + size > OMV_RAW_BUF_SIZE) {
|
if (offset + size > framebuffer_get_buffer_size()) {
|
||||||
jpeg_buffer_overflow = true;
|
jpeg_buffer_overflow = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1301,7 +1303,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, streaming_cb_t streaming_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If two frames fit in ram, use double buffering in streaming mode.
|
// If two frames fit in ram, use double buffering in streaming mode.
|
||||||
doublebuf = ((length*2) <= OMV_RAW_BUF_SIZE);
|
doublebuf = ((length*2) <= framebuffer_get_buffer_size());
|
||||||
|
|
||||||
#if OMV_ENABLE_HM01B0
|
#if OMV_ENABLE_HM01B0
|
||||||
HAL_DCMI_EnableCrop(&DCMIHandle);
|
HAL_DCMI_EnableCrop(&DCMIHandle);
|
||||||
@ -1471,8 +1473,9 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, streaming_cb_t streaming_c
|
|||||||
// within a transfer we have to look at the DMA counter and see how much data was moved.
|
// within a transfer we have to look at the DMA counter and see how much data was moved.
|
||||||
MAIN_FB()->bpp = (offset * MAX_XFER_SIZE) + ((MAX_XFER_SIZE/4) - __HAL_DMA_GET_COUNTER(&DMAHandle))*4;
|
MAIN_FB()->bpp = (offset * MAX_XFER_SIZE) + ((MAX_XFER_SIZE/4) - __HAL_DMA_GET_COUNTER(&DMAHandle))*4;
|
||||||
|
|
||||||
|
uint32_t size = framebuffer_get_buffer_size();
|
||||||
// DMA has most likely corrupted FB alloc state and or more.
|
// DMA has most likely corrupted FB alloc state and or more.
|
||||||
if (MAIN_FB()->bpp > OMV_RAW_BUF_SIZE) {
|
if (MAIN_FB()->bpp > size) {
|
||||||
__fatal_error("JPEG Overflow!");
|
__fatal_error("JPEG Overflow!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1480,7 +1483,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, streaming_cb_t streaming_c
|
|||||||
// In JPEG mode, the DMA uses the frame buffer memory directly instead of the line buffer, which is
|
// In JPEG mode, the DMA uses the frame buffer memory directly instead of the line buffer, which is
|
||||||
// located in a cacheable region and therefore must be invalidated before the CPU can access it again.
|
// located in a cacheable region and therefore must be invalidated before the CPU can access it again.
|
||||||
// Note: The frame buffer address is 32-byte aligned, and the size is a multiple of 32-bytes for all boards.
|
// Note: The frame buffer address is 32-byte aligned, and the size is a multiple of 32-bytes for all boards.
|
||||||
SCB_InvalidateDCache_by_Addr((uint32_t*)MAIN_FB()->pixels, OMV_RAW_BUF_SIZE);
|
SCB_InvalidateDCache_by_Addr((uint32_t*)MAIN_FB()->pixels, size);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// Clean trailing data.
|
// Clean trailing data.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user