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());
|
||||
}
|
||||
|
||||
char *fb_alloc_stack_pointer()
|
||||
{
|
||||
return pointer;
|
||||
}
|
||||
|
||||
__weak NORETURN void fb_alloc_fail()
|
||||
{
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError,
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#define FB_ALLOC_NO_HINT 0
|
||||
#define FB_ALLOC_PREFER_SPEED 1
|
||||
#define FB_ALLOC_PREFER_SIZE 2
|
||||
char *fb_alloc_stack_pointer();
|
||||
void fb_alloc_fail();
|
||||
void fb_alloc_init0();
|
||||
uint32_t fb_avail();
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
#define CONSERVATIVE_JPEG_BUF_SIZE (OMV_JPEG_BUF_SIZE-64)
|
||||
|
||||
extern char _fb_base;
|
||||
extern char _fballoc;
|
||||
framebuffer_t *framebuffer = (framebuffer_t *) &_fb_base;
|
||||
|
||||
extern char _jpeg_buf;
|
||||
@ -200,32 +199,19 @@ int32_t framebuffer_get_depth()
|
||||
|
||||
uint32_t framebuffer_get_frame_size()
|
||||
{
|
||||
switch (framebuffer->bpp) {
|
||||
case -1: {
|
||||
// Invalid frame.
|
||||
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;
|
||||
}
|
||||
}
|
||||
image_t img;
|
||||
framebuffer_initialize_image(&img);
|
||||
return image_size(&img);
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
@ -64,7 +64,8 @@ int32_t framebuffer_get_depth();
|
||||
// otherwise return 0 if the framebuffer is unintialized or invalid (e.g. first frame).
|
||||
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();
|
||||
|
||||
// Return the current buffer address.
|
||||
|
||||
@ -475,7 +475,7 @@ static int sensor_check_buffsize(sensor_t *sensor)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
// 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().
|
||||
uint32_t size = framebuffer_get_buffer_size();
|
||||
if ((sensor.pixformat == PIXFORMAT_BAYER)
|
||||
&& (pixformat == PIXFORMAT_RGB565)
|
||||
&& (MAIN_FB()->u * MAIN_FB()->v * 2 > OMV_RAW_BUF_SIZE)
|
||||
&& (MAIN_FB()->u * MAIN_FB()->v * 1 <= OMV_RAW_BUF_SIZE)) {
|
||||
&& (MAIN_FB()->u * MAIN_FB()->v * 2 > size)
|
||||
&& (MAIN_FB()->u * MAIN_FB()->v * 1 <= size)) {
|
||||
// No change
|
||||
return 0;
|
||||
}
|
||||
@ -921,6 +922,7 @@ void DCMI_VsyncExtiCallback()
|
||||
// within the RAM we have onboard the system.
|
||||
static void sensor_check_buffsize()
|
||||
{
|
||||
uint32_t size = framebuffer_get_buffer_size();
|
||||
uint32_t bpp;
|
||||
|
||||
switch (sensor.pixformat) {
|
||||
@ -938,7 +940,7 @@ static void sensor_check_buffsize()
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -948,7 +950,7 @@ static void sensor_check_buffsize()
|
||||
bpp = 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;
|
||||
}
|
||||
}
|
||||
@ -995,7 +997,7 @@ static void sensor_check_buffsize()
|
||||
}
|
||||
|
||||
// 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()->v -= v_sub;
|
||||
}
|
||||
@ -1109,7 +1111,7 @@ void DCMI_DMAConvCpltUser(uint32_t addr)
|
||||
//
|
||||
uint16_t size = __REV16(*src16);
|
||||
// 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;
|
||||
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.
|
||||
doublebuf = ((length*2) <= OMV_RAW_BUF_SIZE);
|
||||
doublebuf = ((length*2) <= framebuffer_get_buffer_size());
|
||||
|
||||
#if OMV_ENABLE_HM01B0
|
||||
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.
|
||||
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.
|
||||
if (MAIN_FB()->bpp > OMV_RAW_BUF_SIZE) {
|
||||
if (MAIN_FB()->bpp > size) {
|
||||
__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
|
||||
// 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.
|
||||
SCB_InvalidateDCache_by_Addr((uint32_t*)MAIN_FB()->pixels, OMV_RAW_BUF_SIZE);
|
||||
SCB_InvalidateDCache_by_Addr((uint32_t*)MAIN_FB()->pixels, size);
|
||||
#endif
|
||||
}
|
||||
// Clean trailing data.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user